1.验证器基类
<?php
namespace app;
use think\Exception;
use think\Validate;
class BaseValidate extends Validate
{
/**
* 验证规则
*/
protected $rule = [];
/**
* 错误提示信息
*/
protected $message = [];
/**
* 验证场景
*/
protected $scene = [];
/**
* 字段别名映射
*/
protected $field = [
'shop_id' => '店铺ID',
];
/**
* 自定义验证方法:检查记录是否存在
*
* @param mixed $value 字段值
* @param mixed $rule 模型名称
* @param array $data 数据
* @return true|string
*/
protected function checkExist($value, $rule, $data)
{
// 动态加载模型类
$modelClass = '\\app\\model\\' . ucfirst($rule);
if (!class_exists($modelClass)) {
return "模型 {$rule} 不存在";
}
// 检查记录是否存在
$exists = $modelClass::where('id', $value)->exists();
if (!$exists) {
// 动态字段映射
$fieldName = $this->field[$rule] ?? $rule;
return "$fieldName 不存在";
}
return true;
}
/**
* 按 scene 规则,获取并验证请求数据
*
* @param string $scene 场景名称
* @throws Exception
* @return array 验证后的数据
*/
public function readScene($scene)
{
if (!isset($this->scene[$scene])) {
throw new Exception('操作类型不存在');
}
if ($this->scene[$scene]) {
$fields = $this->scene[$scene];
$params = request()->param($this->scene[$scene]);
// 补充未传字段
foreach ($fields as $f) {
if (!isset($params[$f])) {
$params[$f] = null;
}
}
$params['action'] = $scene;
$result = $this->scene($scene)->check($params);
if (!$result) {
throw new Exception($this->getError());
}
} else {
$params = [];
}
return $params;
}
}
2.命令内容–app/command/你的命令内容
<?php
declare(strict_types=1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\facade\App;
class CreateValidate extends Command
{
protected function configure()
{
// 指令配置
$this->setName('validate')
->setDescription('生成一个验证器带自定义验证方法')
->addArgument('name', Argument::REQUIRED, '验证器名称');
}
protected function execute(Input $input, Output $output)
{
// 获取验证器名称
$validateName = $input->getArgument('name');
// 验证器目录和文件路径
$validatePath = App::getAppPath() . 'validate/';
$filePath = $validatePath . $validateName . '.php';
// 检查文件是否已存在
if (file_exists($filePath)) {
$output->writeln('<error>Validate already exists!</error>');
return;
}
// 确定目录是否存在,不存在则创建
if (!is_dir($validatePath)) {
mkdir($validatePath, 0755, true);
}
// 使用 heredoc 生成代码
$content = $this->generateValidateContent($validateName);
// 写入文件
file_put_contents($filePath, $content);
$output->writeln("<info>Validate {$validateName} created successfully!</info>");
}
/**
* 生成验证器内容
*
* @param string $validateName 验证器名称
* @return string 验证器内容
*/
private function generateValidateContent(string $validateName): string
{
// 将内容分行写入,避免 heredoc 转义或字符问题
return <<<PHP
<?php
namespace app\\validate;
use app\\BaseValidate;
class {$validateName} extends BaseValidate
{
}
PHP;
}
}
3.config/console
<?php
// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
// 指令定义
'commands' => [
'model' => \app\command\CreateModel::class,
'validate' => \app\command\CreateValidate::class
],
];
4.可能存在的问题
readScene传进来的是user_id不是id怎么办