Fastadmin后台使用validate进行表单验证

FastAdmin 完整实现前后端表单验证(自动加载 Validate 验证器)

FastAdmin CRUD 表单双重验证教程 | 开启 modelValidate 自动调用 Validate 验证器,解决前端 data-rule 失效问题。

目录

前言

环境说明

一、整体架构说明

[二、步骤 1:创建 Validate 验证器](#二、步骤 1:创建 Validate 验证器)

[三、步骤 2:控制器开启自动验证](#三、步骤 2:控制器开启自动验证)

工作原理

[四、步骤 3:视图页面添加前端辅助校验(add.html/edit.html)](#四、步骤 3:视图页面添加前端辅助校验(add.html/edit.html))

五、常见踩坑清单(高频问题)

[坑 1:验证器类名、命名空间和模型不一致](#坑 1:验证器类名、命名空间和模型不一致)

[坑 2:忘记开启 modelSceneValidate = true](#坑 2:忘记开启 modelSceneValidate = true)

[坑 3:规则写成 between1,5](#坑 3:规则写成 between[1,5])

[坑 4:前端 data-rule 正常,关闭 JS 后非法数据可以提交](#坑 4:前端 data-rule 正常,关闭 JS 后非法数据可以提交)

[坑 5:修改代码后验证不生效](#坑 5:修改代码后验证不生效)

[坑 6:字段名称不匹配](#坑 6:字段名称不匹配)

六、拓展方案:不使用自动加载,手动调用验证器

七、总结最佳实践


前言

很多 FastAdmin 开发者只使用前端data-rule表单校验,但前端 JS 验证可以被用户禁用、直接绕过,存在严重安全漏洞 。 正确方案:前端友好提示 + 后端 Validate 强制校验双层防护

FastAdmin 内置原生支持同名验证器自动加载机制,只需两行控制器属性配置,新增 / 编辑自动触发add/edit验证场景。 本文基于标准 CRUD 生成的控制器、视图完整演示,以商品评价评分(1~5 分)案例实战。

环境说明

  • FastAdmin V1.3.x / ThinkPHP5.1
  • CRUD 自动生成控制器,原生add/edit事务代码不做大规模修改
  • 表单默认格式 name="row字段名"

一、整体架构说明

两层验证分工:

  1. 前端视图(Nice Validator):页面实时提示,优化用户体验,非强制
  2. 后端 Validate 验证器:强制校验,不可绕过,核心安全防线

FastAdmin 自动验证机制逻辑:

php 复制代码
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));

// $modelSceneValidate=true 自动拼接 .add / .edit 场景

$validate = $name . '.edit';

要求:模型类名 和 Validate 验证器类名完全一致,命名空间保持统一

二、步骤 1:创建 Validate 验证器

路径:application/admin/validate/GoodsEvaluation.php

模型:app\admin\model\GoodsEvaluation 验证器:app\admin\validate\GoodsEvaluation

php 复制代码
<?php

namespace app\admin\validate;

use think\Validate;

class GoodsEvaluation extends Validate
{
    /**
     * 验证规则
     */
    protected $rule = [
        'num'   => 'require|number|between:1,5',
        'desc'  => 'require|max:255',
    ];
    /**
     * 自定义错误提示
     */
    protected $message = [
        'num.require'   => '请输入评价分数',
        'num.number'    => '评价分数必须是数字',
        'num.between'   => '评价分数必须在1到5之间',
        'desc.require'  => '请输入评价内容',
        'desc.max'      => '评价内容最多255个字符',
    ];
    /**
     * 验证场景
     * add:新增页面;edit:编辑页面
     */
    protected $scene = [
        'add'  => ['num','desc'],
        'edit' => ['num','desc'],
    ];

    /**
     * 自定义字段中文名称(可选,错误提示更友好)
     */
    public function __construct(array $rules = [], $message = [], $field = [])
    {
        $this->field = [
            'num'   => __('Num'),
            'desc'  => __('Desc')
        ];
        parent::__construct($rules, $message, $field);
    }

}

⚠️ 避坑重点 规则分隔符必须是英文冒号between:1,5,禁止写成 between1,5,语法错误会导致验证完全失效!

三、步骤 2:控制器开启自动验证

打开控制器 application/admin/controller/GoodsEvaluation.php 在控制器类内部添加两个核心属性:

php 复制代码
protected $modelValidate = true;      // 开启模型自动验证

protected $modelSceneValidate = true;  // 开启场景验证(自动识别add/edit)

完整控制器示例片段:

php 复制代码
class GoodsEvaluation extends Backend
{
    protected $model = null;
    // 开启自动验证与场景验证【核心配置】
    protected $modelValidate = true;
    protected $modelSceneValidate = true;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\GoodsEvaluation();
    }

}

工作原理

开启两个参数后:

  1. 访问 add 提交:自动加载 scene('add')
  2. 访问 edit 提交:自动加载 scene('edit')
  3. 验证失败抛出ValidateException,被 catch 捕获,弹窗输出自定义错误文本

不需要手动new Validate(),原生事务代码完全兼容,无需大幅改造。

四、步骤 3:视图页面添加前端辅助校验(add.html/edit.html)

前端data-rule仅作为体验优化,不能替代后端验证。 很多开发者反馈range(1-5)失效,推荐使用 min + max 写法:

html 复制代码
<div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Num')}:</label>
        <div class="col-xs-12 col-sm-8">
            <input id="c-num" data-rule="required;integer;range(1~5)" data-msg="请填写1-5的整数分值" class="form-control" name="row[num]" type="number" min="1" max="5" value="{$row.num|htmlentities}">
        </div>
    </div>
    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Desc')}:</label>
        <div class="col-xs-12 col-sm-8">
            <textarea id="c-desc" data-rule="required" class="form-control " rows="5" max="255" name="row[desc]" cols="50">{$row.desc|htmlentities}</textarea>
        </div>
    </div>

五、常见踩坑清单(高频问题)

坑 1:验证器类名、命名空间和模型不一致

模型:app\admin\model\GoodsEvaluation 验证器必须:app\admin\validate\GoodsEvaluation,大小写必须完全匹配。

坑 2:忘记开启$modelSceneValidate = true

只开modelValidate不会自动读取scene'edit',会执行全部规则,引发意料之外的校验。

坑 3:规则写成between1,5

ThinkPHP 验证规则分隔符为冒号 ✅between:1,5

坑 4:前端 data-rule 正常,关闭 JS 后非法数据可以提交

✅解决方案:永远依靠后端 Validate 作为最终防线,前端仅做体验优化。

坑 5:修改代码后验证不生效

清除项目runtime/cache缓存,浏览器 Ctrl+F5 强制刷新页面。

坑 6:字段名称不匹配

表单提交 rownum,后端$this->request->post("row/a")解析后数组键名就是num,验证器规则字段保持一致即可。

六、拓展方案:不使用自动加载,手动调用验证器

部分场景不想开启全局自动验证,可以在控制器手动调用:

php 复制代码
use app\admin\validate\GoodsEvaluation;

$params = $this->request->post("row/a");
$validate = new GoodsEvaluation();
if(!$validate->scene('edit')->check($params)){
    $this->error($validate->getError());
}

七、总结最佳实践

  1. 强制后端 Validate 校验,不能省略,杜绝前端绕过风险;
  2. 控制器开启 modelValidate + modelSceneValidate,复用原生 CRUD 事务代码;
  3. 验证器区分add/edit场景,按需定义规则;
  4. 视图增加data-rule前端实时提示,提升操作体验;
  5. 严格注意命名空间、类名、验证规则语法,避开常见 bug。
相关推荐
旋生万物12 小时前
【终极实战】用Python从零“生成“一个宇宙:螺旋干涉模型的代码实现
开发语言·前端·人工智能·react.js·php·wpf
艾醒(AiXing-w)15 小时前
LangChain 1.0 入门(三):稳定性双核心——重试机制+速率限速器参数详解与实战
开发语言·langchain·php
宸津-代码粉碎机16 小时前
FastUtil+AI多Agent实战:Java AI项目性能终极加速方案
java·服务器·开发语言·python·安全·php
练习时长两年半的RL练习生18 小时前
与AI对话后对 Actor-Critic 中 TD Target 的 a‘ 来源总结
开发语言·人工智能·php
Sagittarius_A*19 小时前
【好靶场】PHP反序列化绕过
web安全·信息安全·php·代码审计·反序列化绕过
孫治AllenSun20 小时前
【系统安全】信息脱敏存储:场景、需求与实现方案详解
安全·系统安全·php
aixingpan1 天前
aixingpan.cn API开发文档:api_docs_errors接口指南
前端·php
FYKJ_20101 天前
django学习成绩预警系统10905
java·javascript·spring boot·python·spark·django·php
BingoGo1 天前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
后端·php
JaguarJack1 天前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
后端·php·服务端