Hyperf 驗證 trait

ezreal_rao發表於2019-12-10

模仿LaravelValidatesRequest寫的一個Trait,僅供參考。

trait類:
<?php
namespace App\Controller;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Contract\ValidatorInterface;
use Hyperf\Validation\ValidationException;

trait ValidatesRequests
{
    /**
     * @param  ValidatorInterface|array  $validator
     * @param RequestInterface|null $request
     * @return array
     *
     * @throws ValidationException
     */
    public function validateWith($validator, RequestInterface $request = null)
    {
        $request = $request ?? request();

        if (is_array($validator)) {
            $validator = $this->getValidationFactory()->make($request->all(), $validator);
        }

        return $validator->validate();
    }

    /**
     * @param RequestInterface $request
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     * @return mixed
     *
     * @throws ValidationException
     */
    public function validate(RequestInterface $request, array $rules,
                             array $messages = [], array $customAttributes = [])
    {
        return $this->getValidationFactory()->make(
            $request->all(), $rules, $messages, $customAttributes
        )->validate();
    }

    /**
     * @param $errorBag
     * @param RequestInterface $request
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     * @return mixed
     *
     * @throws ValidationException
     */
    public function validateWithBag($errorBag, RequestInterface $request, array $rules,
                                    array $messages = [], array $customAttributes = [])
    {
        try {
            return $this->validate($request, $rules, $messages, $customAttributes);
        } catch (ValidationException $e) {
            $e->errorBag = $errorBag;
            throw $e;
        }

    }

    /**
     * @return ValidatorFactoryInterface
     */
    protected function getValidationFactory()
    {
        return make(ValidatorFactoryInterface::class);
    }
}
用法:

AbstractController

use ValidatesRequests;

然後就可以在繼承AbstractController所有的控制器中這樣使用了:

public function index(RequestInterface $request)
    {
        $this->validate($request, [
            'id' => 'required|integer'
        ], [], [
            'id' => 'ID',
        ]);
    }
異常類

定義一個異常類來catch到驗證異常

<?php
namespace App\Exception;

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

class ValidationException extends ValidationExceptionHandler
{
    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        $this->stopPropagation();
        /** @var \Hyperf\Validation\ValidationException $throwable */
        $body = json_encode([
            'errors' => $throwable->validator->errors()->first()
        ], JSON_UNESCAPED_UNICODE);
        return $response->withHeader('Content-Type', 'application/json')->withStatus($throwable->status)->withBody(new SwooleStream($body));
    }

    public function isValid(Throwable $throwable): bool
    {
        return $throwable instanceof \Hyperf\Validation\ValidationException;
    }
}

然後在config/autoload/exceptions.php中新增

return [
    'handler' => [
        'http' => [
            App\Exception\Handler\SystemExceptionHandler::class,
            App\Exception\ValidationException::class, //該處就是驗證異常類 必須放在AppExceptionHandler上
            App\Exception\Handler\AppExceptionHandler::class,
        ],
    ],
];
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章