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。
相关推荐
用户4130294883465 小时前
从 0 到 1 用 PHP 实现 Cron 表达式解析器(附完整源码)
php
JSON_L6 小时前
Fastadmin关联查询报错 method not exist:think\db\Query->XXX
php·fastadmin
DFT计算杂谈1 天前
SCIENTIFIC REPORTS 非 van der Waals可调二维磁性材料设计平台
开发语言·php
凡尘——雨落凡尘1 天前
PHP实战复盘:高并发限流、防刷、验证码、会话安全、CSRF防护导致站点稳定性与安全加固实战
php·csrf 防护·csrf 攻击
2601_965798471 天前
Bostami Portfolio Template Review: Speed, Code & SEO Test
php
AC赳赳老秦1 天前
开源组件版本数据监控:OpenClaw 抓取公开版本信息,自动提醒更新与安全风险
前端·python·安全·开源·github·php·openclaw
漏刻有时2 天前
PHP GeoJSON转PNG地图渲染程序开发笔记、源码解读、问题复盘与整改方案
android·笔记·php
always_TT2 天前
【Python 日志记录:logging 模块入门】
开发语言·python·php
Immortal__y2 天前
Upload-Labs 关卡防御方式
php