hyperf: 校验接收到的参数

一,官方文档地址

https://hyperf.wiki/3.1/#/zh-cn/validation

安装:  这个第三方库默认没有安装,需要我们手动安装

$ composer require hyperf/validation

二,封装要用的类

1,app/Lib/BaseValidator.php

<?php
namespace App\Lib;

use App\Lib\ValidateException;
//use App\Lib\_Validator\Rules\MobileRule;
use App\Lib\RuleInterface;
use Hyperf\Context\ApplicationContext;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;

/**
 * 更多内置规则参考:https://learnku.com/docs/laravel/6.x/validation/5144#available-validation-rules
 * accepted  yes、 on 或者是 1。这在验证是否同意"服务条款"的时候非常有用。
 * active_url URL 一个合法的 URL,根据 PHP 函数 checkdnsrr。
 * date 必须是一个合法的日期,根据 PHP 函数 strtotime
 * date_format:format 必须符合给定的 format 的格式,根据 PHP 函数 date_parse_from_format
 * after:date 在给定日期之后,该日期将被传递到 PHP 的 strtotime 函数
 * before:date 在给定日期之前,该日期将被传递到 PHP 的 strtotime 函数
 * alpha  全字母
 * alpha_dash 字母、数字、中划线或下划线字符
 * alpha_num 全部由字母和数字构成
 * between:min,max 给定的 min 和 max 之间。字符串、数字以及文件都将使用大小规则进行比较
 * confirmed 比如,需要验证此规则的字段是  password,那么在输入中必须有一个与之相同的 password_confirmation 字段
 * different:field 必须与指定的 field 字段的值不同
 * digits:value 必须是一个 数字 并且必须满足 value 设定的精确长度
 * digits_between:min,max 长度必须介于 min 和 max 之间
 * email 合法的电子邮件地址
 * mobile 合法的手机号码
 * code 手机短信验证码
 * exists:table,column,where 必须在指定的数据库的表中存在 (column、where可选) 例:'email' => 'exists:staff,email,account_id,1'
 * unique:table,column,except,idColumn 数据库的表中唯一 (except:强制忽略一个给定的 ID)
 * 例: 强制忽略一个给定的 ID : 'email' => 'unique:users,email_address,10'
 *
 * image 必须是一个图片 (jpeg, png, bmp 或者 gif)
 * in:foo,bar,... 值必须在给定的列表中存在
 * not_in:foo,bar,... 值不在给定的列表中存在
 * integer 整数
 * ip 合法的 IP 地址
 * max:value 值必须小于最大值 value。字符串,数值,数组,文件大小的计算方式都与 size 规则一致。
 * min:value 值必须大于最小值 value。字符串,数值,数组,文件大小的计算方式都与 size 规则一致。
 * mimes:foo,bar,... 文件的 MIME 类型必须在给定的列表中。
 * numeric 数值、数值字符串
 * float 浮点数
 * regex:pattern 正则表达式
 * required 必须存在验证
 * required_if:field,value 如果 field 字段值等于 value ,那么该验证为必须值
 * required_with:foo,bar,... 仅当 其它指定的字段存在的时候,验证此规则的值必须存在。
 * required_without:foo,bar,... 仅当 其它指定的字段 ‘有一个’ 不存在的时候,验证此规则的值必须存在。
 * required_without_all:foo,bar,... 仅当 其它指定的字段 ‘都不存在’ 的时候,验证此规则的值必须存在。
 * same:field 验证此规则的值必须与给定的 field 字段的值相同。
 * size:value 对于字符串,value 代表字符的个数;对于数字,value 代表它的整数值,对于文件,value 以KB为单位
 * url 合法的 URL
 * gt:value 大于
 * gte:value 大于等于
 * lt:value 小于
 * lte:value 小于等于
 */
class BaseValidator
{
    protected static $extends = [];

    public static function getValidator(): ValidatorFactoryInterface
    {
        static $validator = null;
        if (is_null($validator)) {
            $container = ApplicationContext::getContainer();
            $validator = $container->get(ValidatorFactoryInterface::class);
            self::initExtends();
            self::registerExtends($validator, self::$extends);
        }

        return $validator;
    }

    protected static function initExtends()
    {
        // 更多自定义的扩展
        self::$extends = [
           // MobileRule::NAME => new MobileRule,
        ];
    }

    protected static function registerExtends(ValidatorFactoryInterface $validator, array $extends)
    {
        foreach ($extends as $key => $extend) {
            if ($extend instanceof RuleInterface) {
                $validator->extend($key, function (...$args) use ($extend) {
                    return call_user_func_array([$extend, RuleInterface::PASSES_NAME], $args);
                });
                $validator->replacer($key, function (...$args) use ($extend) {
                    return call_user_func_array([$extend, RuleInterface::MESSAGE_NAME], $args);
                });
            }
        }
    }

    /**
     * @param array $data
     * @param array $rules
     * @param array $messages
     * @param bool $firstError
     * @return bool
     * @throws ValidateException
     */
    public static function make(array $data, array $rules, array $messages = [], bool $firstError = true): bool
    {

        $validator = self::getValidator();
        if (empty($messages)) {
            $messages = self::messages();
        }
        $valid = $validator->make($data, $rules, $messages);
        if ($valid->fails()) {
            $errors = $valid->errors();
            $error = $firstError ? $errors->first() : $errors;
            throw new ValidateException(1501,$error);
        }
        return true;
    }
    // 这个其实用处不大
    public static function messages(): array
    {
        return [];
    }
}

 

2,app/Lib/ValidateException.php

<?php

namespace App\Lib;

use App\Constants\ErrorCode;
use Exception;
use Hyperf\Server\Exception\ServerException;
use Throwable;

class ValidateException extends Exception
{

    public function __construct(int $code = 1501, string $message = null)
    {

        echo "ValidateException接收到的错误:";
        var_dump($message);
        echo "/n错误显示完成/n";

        parent::__construct($message, $code, null);
        /*
        if (is_null($message)) {
            $message = ErrorCode::getMessage($code);
        }

        parent::__construct($message, $code, $previous);
        */
    }
}

 

3,app/Lib/RuleInterface.php

<?php
namespace App\Lib;

use Hyperf\Validation\Validator;

interface RuleInterface
{
    const PASSES_NAME = 'passes';
    const MESSAGE_NAME = 'message';

    /**
     * @param $attribute
     * @param $value
     * @param $parameters
     * @param Validator $validator
     * @return bool
     */
    public function passes($attribute, $value, $parameters, Validator $validator): bool;

    /**
     *
     * @param $message
     * @param $attribute
     * @param $rule
     * @param $parameters
     * @param Validator $validator
     * @return string
     */
    public function message($message, $attribute, $rule, $parameters, Validator $validator): string;
}

 

三,调用我们定义的校验类

1,调用

controller/ImageController.php

    public function imagedetail(RequestInterface $request, ResponseInterface $response) {
        //unique:user,id
        BaseValidator::make($request->all(),
            ['nickname' => 'required|min:2',
             'id' => 'required|numeric|min:3',],
            [
            // 错误信息应该尽量在验证器的语言文件里面定义(以下是演示)
            'nickname.required'=>'昵称 必须填写',
            'nickname.min'=>'昵称长度最小两个字符',
            'id.required'=>'id 必须填写',
            'id.numeric'=>'id必须为数值类型',
            'id.min'=>'id值最小为3',
        ]);
        $nickname = $request->input("nickname");
        echo "验证通过,nickname:".$nickname."\n";

        $data = [
            'nickname' => $nickname,
        ];
        return $response->json($data);

    }

2,发生异常时的处理代码:

app/Exception/Handler/AppExceptionHandler.php

        if ($throwable instanceof ValidateException) {
            //当前是自定义异常时,只返回不再写入到日志
            echo "捕捉到的是自定义异常ValidateException\n";
            // 格式化输出,  去掉JSON_UNESCAPED_UNICODE
            $data = json_encode([
                'code' => $throwable->getCode(),
                'message' => $throwable->getMessage(),
            ]);
            // 阻止异常冒泡
            $this->stopPropagation();
            //返回json
            return $response->withStatus(200)->withBody(new SwooleStream($data));
        }

四,测试效果

 

posted @   刘宏缔的架构森林  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2023-02-15 thinkphp:允许接口跨域访问(thinkphp v6.0.12LTS)
点击右上角即可分享
微信分享提示