前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记录hyperf框架表单验证中的细枝末节

记录hyperf框架表单验证中的细枝末节

作者头像
Mandy的名字被占用了
发布2021-07-15 15:36:08
9720
发布2021-07-15 15:36:08
举报

简介

本文对使用hyperf框架的表单验证中遇到的两个小细节做一个分享。具体的两点如下:

  1. 自定义验证异常数据返回格式。该问题主要在下面的第3点体现。
  2. 自定义验证规则。该问题主要在下面的第6点体现。
  3. 一款免费的在线答题小程序软件

自定义验证异常格式

1. 首选根据官方文档进行操作,安装验证组件。

代码语言:javascript
复制
composer require hyperf/validation
php bin/hyperf.php vendor:publish hyperf/translation
php bin/hyperf.php vendor:publish hyperf/validation

2. 接着在配置文件config/autoload/middlewares.php,中添加验证异常中间件。这里的异常中间件为框架自带的异常处理中间件。

代码语言:javascript
复制
<?php

declare(strict_types=1);
/**
 * This file is part of api.
 *
 * @link     https://www.qqdeveloper.io
 * @document https://www.qqdeveloper.wiki
 * @contact  2665274677@qq.com
 * @license  Apache2.0
 */
use Hyperf\Validation\Middleware\ValidationMiddleware;

return [
    'http' => [
        ValidationMiddleware::class,
    ],
];

3. 自定义一个验证异常处理器。这一步是最重要的异步,官方文档有提及到使用框架自带的异常处理器,如果你没有特别的需求,可以直接按照官方文档操作即可。由于我们的异常接口返回数据格式要返回一个json的格式,而不是默认的一个文本格式。

代码语言:javascript
复制
<?php

declare(strict_types=1);
/**
 * This file is part of api.
 *
 * @link     https://www.qqdeveloper.io
 * @document https://www.qqdeveloper.wiki
 * @contact  2665274677@qq.com
 * @license  Apache2.0
 */
namespace App\Exception\Handler;

use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Validation\ValidationException;
use Psr\Http\Message\ResponseInterface;
use Throwable;

/**
 * 自定义表单验证异常处理器.
 *
 * Class FromValidateExceptionHandler
 */
class FromValidateExceptionHandler extends ExceptionHandler
{
    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        if ($throwable instanceof ValidationException) {
            // 格式化异常数据格式
            $data = json_encode([
                'code' => $throwable->getCode(),
                // 获取异常信息
                'message' => $throwable->validator->errors()->first(),
                'data' => [],
            ]);
            $this->stopPropagation();
            return $response->withStatus(422)->withBody(new SwooleStream($data));
        }

        return $response;
    }
    // 异常处理器处理该异常
    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}

4. 编写完验证异常处理器之后,将该异常添加到异常配置文件config/autoload/exceptions.php中。由于hyperf中异常处理器的配置顺序会影响到异常的处理顺序,这里可以随机顺序配置。

代码语言:javascript
复制
<?php

declare(strict_types=1);
/**
 * This file is part of api.
 *
 * @link     https://www.qqdeveloper.io
 * @document https://www.qqdeveloper.wiki
 * @contact  2665274677@qq.com
 * @license  Apache2.0
 */
use App\Exception\Handler\FromValidateExceptionHandler;

return [
    'handler' => [
        'http' => [
            Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
            App\Exception\Handler\AppExceptionHandler::class,
            // 自定义的验证异常处理器
            FromValidateExceptionHandler::class,
        ],
    ],
];

5. 剩下的代码就按照文档操作,编写一个独立的验证类文件,在对应的控制器中方法采用依赖注入的方式调用即可。输出的结果,格式就和下面的一样了。

自定义验证规则

为什么有自定义验证规则呢?无非就是官网提供的验证规则属于常见的,可能你会根据项目的需要,自定义一些规则,这时候就需要你单独定义一个规则了。我们这里创建一个money的验证规则,验证金额是否合法。

  1. 创建一个监听器。
代码语言:javascript
复制
<?php

declare(strict_types=1);
/**
 * This file is part of api.
 *
 * @link     https://www.qqdeveloper.io
 * @document https://www.qqdeveloper.wiki
 * @contact  2665274677@qq.com
 * @license  Apache2.0
 */
namespace App\Listener;

use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Event\ValidatorFactoryResolved;

/**
 * 验证器监听器.
 *
 * Class ValidatorFactoryResolvedListener
 */
class ValidatorFactoryResolvedListener implements ListenerInterface
{
    public function listen(): array
    {
        return [
            ValidatorFactoryResolved::class,
        ];
    }

    public function process(object $event)
    {
        /** @var ValidatorFactoryInterface $validatorFactory */
        $validatorFactory = $event->validatorFactory;
        // 注册了 money 验证器
        $validatorFactory->extend('money', function ($attribute, $value, $parameters, $validator) {
            var_dump(time());
            $pregResult = preg_match('/^[0-9]{1,20}(\.[0-9]{1,2})?$/', $value);
            // true则返回错误信息;false则不返回错误,表示验证通过
            return empty($pregResult) ? true : false;
        });
        $validatorFactory->replacer('money', function ($message, $attribute, $rule, $parameters) {
            return str_replace(':money', $attribute, $message);
        });
    }
}

2. 注册监听器到config/autoload/listeners配置文件中。

代码语言:javascript
复制
<?php

declare(strict_types=1);
/**
 * This file is part of api.
 *
 * @link     https://www.qqdeveloper.io
 * @document https://www.qqdeveloper.wiki
 * @contact  2665274677@qq.com
 * @license  Apache2.0
 */
use App\Listener\ValidatorFactoryResolvedListener;

return [
    ValidatorFactoryResolvedListener::class,
];

3. 自定义一个独立验证类文件。

代码语言:javascript
复制
<?php

declare(strict_types=1);
/**
 * This file is part of api.
 *
 * @link     https://www.qqdeveloper.io
 * @document https://www.qqdeveloper.wiki
 * @contact  2665274677@qq.com
 * @license  Apache2.0
 */
namespace App\Request;

use Hyperf\Validation\Request\FormRequest;

class FooRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'money' => 'money',
        ];
    }
}

4. 自定义验证字段信息。找到storage/languages/zh_CN/validation.php文件。在下面添加如下两行代码,关于en文件下的验证字段配置信息,可以添加也可以不添加,根据实际需要添加即可。

代码语言:javascript
复制
'money' => ':attribute格式错误',
'attributes' => [
    'money' => '金额',
],

5. 在对应的控制器中使用依赖注入的方式对独立的验证类文件进行注访问。这样我们的一个独立验证规则就可以配置好了。效果如下:

6. 或许这么定义之后,发现自定义规则没有起作用,这种情况,获取是你没有传递该参数名导致的。只有你传递了参数名,该验证规则才会生效。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卡二条的技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 自定义验证异常格式
  • 自定义验证规则
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档