php框架hyperf增加验证场景,仿thinkphp框架,可增加自定义方法,可根据场景增删 验证规则

环境:php8,centos7.2
hyperf版本:2.2

由于hyperf框架 没有自带验证场景,所以本人参考thinkphp框架写了一个,并非完全实现了thinkphp框架的验证层,只是根据本人使用,简单化实现,如果写得不好,大佬们请轻喷

验证器基础类:


namespace App\Validate\Api;

use Hyperf\Di\Annotation\Inject;
use App\Exception\ErrorMessageException;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;

abstract class BaseValidate
{
    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;

    protected $rule = [];
    protected $message = [];
    protected $parameters = [];

    /**
     * 规则
     * @return array
     */
    protected abstract function rule(): array;

    /**
     * 自定义,提示语
     * @return array
     */
    protected abstract function message(): array;

    /**
     * 自定义方法,以匿名方式命名
     * @return array
     */
    protected abstract function callBack(): array;

    public function __construct()
    {
        $rules = $this->rule();
        foreach ($rules as $key => $rule) {
            if (is_string($rule)) {
                $rules[$key] = explode("|", $rule);
            }
        }
        $this->rule = $rules;
        $this->message = $this->message();
    }

    protected function only(array $ruleArr): self
    {
        $ruleArr = array_flip($ruleArr);
        $this->rule = array_intersect_key($this->rule, $ruleArr);
        return $this;
    }

    /**
     * @param $field
     * @param $rule
     */
    protected function append(string $field, $rule): self
    {
        $rule = is_array($rule) ? $rule : explode("|", $rule);
        if (isset($this->rule[$field])) {
            $this->rule[$field] = array_unique(array_merge($this->rule[$field], $rule));
        }
        return $this;
    }

    protected function remove(string $field, $rule): self
    {
        $rule = is_array($rule) ? $rule : explode("|", $rule);
        if (isset($this->rule[$field])) {
            $this->rule[$field] = array_diff($this->rule[$field], $rule);
        }
        return $this;
    }

    final public function scene(string $scene): self
    {
        $scene = 'scene_' . $scene;
        $sceneName = preg_replace_callback('/_+([a-z])/', function ($matches) {
            return strtoupper($matches[1]);
        }, $scene);
        if (method_exists($this, $sceneName)) {
            return call_user_func([$this, $sceneName]);
        }
        return $this;
    }


    final public function validate(array $data)
    {
        $callBackList = $this->callBack();
        $validationFactory = $this->validationFactory;
        foreach ($callBackList as $funcName => $callBack) {
            $validationFactory->extend($funcName, $callBack);
        }
        $this->parameters = $data;
        $validator = $validationFactory->make($data, $this->rule, $this->message);
        if ($validator->fails()) {
            $error = $validator->errors();
            throw new ErrorMessageException($error->first());
        }
    }
}

验证器 范例:

<?php
namespace App\Validate\Api;


use App\Exception\ErrorMessageException;

class TestValidate extends BaseValidate
{
    protected function rule(): array
    {
        return [
            'name' => "required|integer|checkName",
            'phone' => "required|checkPhone",
        ];
    }

    protected function message(): array
    {
        return [
            'name.required' => '请填写姓名',
            'phone.required' => '请手机号',
            'phone.array' => '手机号的格式不对',
            'name.integer' => '姓名需要是整型',
        ];
    }

    protected function callBack(): array
    {
        return [
            'checkName' => function ($attribute, $value, $parameters, $validator) {
                if ($value != 111) {
                    throw new ErrorMessageException("这里是自定义验证器checkName");
                }
                return true;
            },
            'checkPhone' => function ($attribute, $value, $parameters, $validator) {
                if ($value != "abc") {
                    throw new ErrorMessageException("这里是自定义验证器checkPhone");
                }
                return true;
            }
        ];
    }

    /*******************************************************************  场景 *******************************************************************/
    protected function sceneTest1()
    {
        return $this->only(['phone'])->remove("phone", ["checkPhone"])->append("phone", "array");
    }

    protected function sceneTest2()
    {
        return $this->only(['name', 'phone']);
    }

    protected function sceneTest3()
    {
        return $this->only(['name', 'phone'])->append("name", ["integer"])->remove("name",['checkName']);
    }}

控制器调用 验证器

namespace App\Controller\Api;

use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use App\Validate\Api\TestValidate;

/**
 * @AutoController()
 * Class TestController
 * @package App\Controller\Api
 */
class TestController
{
    /**
     * @Inject
     * @var RequestInterface
     */
    protected $request;

    /**
     * @Inject()
     * @var TestValidate
     */
    private $testValidate;

    public function test1()
    {
        $this->testValidate->scene('test1')->validate($this->request->all());
        return ["res"=>"恭喜通过"];
    }

    public function test2()
    {
        $this->testValidate->scene('test2')->validate($this->request->all());
        return ["res"=>"恭喜通过"];
    }

    public function test3()
    {
        $this->testValidate->scene('test3')->validate($this->request->all());
        return ["res"=>"恭喜通过"];
    }}

请求演示,这里选几个场景来演示,有兴趣的朋友,可以自己根据自己需要测试
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述