Commit ae89acf9 authored by 王源's avatar 王源 🎧

添加自定义异常相关文件

parent 89d6c6d5
......@@ -10,7 +10,9 @@
}
],
"require": {
"hyperf/db-connection": "^1.1@dev"
"ext-json": "*",
"hyperf/db-connection": "^1.1@dev",
"hyperf/validation": "^1.1@dev"
},
"minimum-stability": "dev",
"autoload": {
......
<?php
namespace Meibuyu\Micro\Validator;
use Hyperf\Utils\MessageBag;
use Meibuyu\Micro\Validator\Contracts\ValidatorInterface;
use Meibuyu\Micro\Validator\Exceptions\ValidatorException;
abstract class AbstractValidator implements ValidatorInterface
{
/**
* @var int
*/
protected $id = null;
/**
* Validator
*
* @var object
*/
protected $validator;
/**
* Data to be validated
*
* @var array
*/
protected $data = array();
/**
* Validation Rules
*
* @var array
*/
protected $rules = array();
/**
* Validation Custom Messages
*
* @var array
*/
protected $messages = array();
/**
* Validation Custom Attributes
*
* @var array
*/
protected $attributes = array();
/**
* Validation errors
*
* @var MessageBag
*/
protected $errors = array();
/**
* Set Id
*
* @param $id
* @return AbstractValidator
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Set data to validate
*
* @param array $data
* @return $this
*/
public function with(array $data)
{
$this->data = $data;
return $this;
}
/**
* Return errors
*
* @return array
*/
public function errors()
{
return $this->errorsBag()->all();
}
/**
* Errors
*
* @return MessageBag
*/
public function errorsBag()
{
return $this->errors;
}
/**
* Pass the data and the rules to the validator
*
* @param string $action
* @return boolean
*/
abstract public function passes($action = null);
/**
* Pass the data and the rules to the validator or throws ValidatorException
*
* @param string $action
* @return boolean
* @throws ValidatorException
*/
public function passesOrFail($action = null)
{
if (!$this->passes($action)) {
throw new ValidatorException($this->errorsBag());
}
return true;
}
/**
* Get rule for validation by action ValidatorInterface::RULE_CREATE or ValidatorInterface::RULE_UPDATE
*
* Default rule: ValidatorInterface::RULE_CREATE
*
* @param null $action
* @return array
*/
public function getRules($action = null)
{
$rules = $this->rules;
if (isset($this->rules[$action])) {
$rules = $this->rules[$action];
}
return $this->parserValidationRules($rules, $this->id);
}
/**
* Set Rules for Validation
*
* @param array $rules
* @return $this
*/
public function setRules(array $rules)
{
$this->rules = $rules;
return $this;
}
/**
* Get Custom error messages for validation
*
* @return array
*/
public function getMessages()
{
return $this->messages;
}
/**
* Set Custom error messages for Validation
*
* @param array $messages
* @return $this
*/
public function setMessages(array $messages)
{
$this->messages = $messages;
return $this;
}
/**
* Get Custom error attributes for validation
*
* @return array
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Set Custom error attributes for Validation
*
* @param array $attributes
* @return $this
*/
public function setAttributes(array $attributes)
{
$this->attributes = $attributes;
return $this;
}
/**
* Parser Validation Rules
*
* @param $rules
* @param null $id
* @return array
*/
protected function parserValidationRules($rules, $id = null)
{
if (null === $id) {
return $rules;
}
array_walk($rules, function (&$rules, $field) use ($id) {
if (!is_array($rules)) {
$rules = explode("|", $rules);
}
foreach ($rules as $ruleIdx => $rule) {
// get name and parameters
@list($name, $params) = array_pad(explode(":", $rule), 2, null);
// only do someting for the unique rule
if (strtolower($name) != "unique") {
continue; // continue in foreach loop, nothing left to do here
}
$p = array_map("trim", explode(",", $params));
// set field name to rules key ($field) (laravel convention)
if (!isset($p[1])) {
$p[1] = $field;
}
// set 3rd parameter to id given to getValidationRules()
$p[2] = $id;
$params = implode(",", $p);
$rules[$ruleIdx] = $name . ":" . $params;
}
});
return $rules;
}
}
\ No newline at end of file
<?php
namespace Meibuyu\Micro\Validator\Contracts;
use Hyperf\Utils\MessageBag;
use Meibuyu\Micro\Validator\Exceptions\ValidatorException;
interface ValidatorInterface
{
const RULE_CREATE = 'create';
const RULE_UPDATE = 'update';
/**
* Set Id
*
* @param $id
* @return ValidatorInterface
*/
public function setId($id);
/**
* With
*
* @param array
* @return $this
*/
public function with(array $input);
/**
* Pass the data and the rules to the validator
*
* @param string $action
* @return boolean
*/
public function passes($action = null);
/**
* Pass the data and the rules to the validator or throws ValidatorException
*
* @param string $action
* @return boolean
* @throws ValidatorException
*/
public function passesOrFail($action = null);
/**
* Errors
*
* @return array
*/
public function errors();
/**
* Errors
*
* @return MessageBag
*/
public function errorsBag();
/**
* Set Rules for Validation
*
* @param array $rules
* @return $this
*/
public function setRules(array $rules);
/**
* Get rule for validation by action ValidatorInterface::RULE_CREATE or ValidatorInterface::RULE_UPDATE
*
* Default rule: ValidatorInterface::RULE_CREATE
*
* @param $action
* @return array
*/
public function getRules($action = null);
}
\ No newline at end of file
<?php
namespace Meibuyu\Micro\Validator\Exceptions;
use Hyperf\Utils\Contracts\MessageBag;
class ValidatorException extends \Exception
{
/**
* @var MessageBag
*/
protected $messageBag;
/**
* @param MessageBag $messageBag
*/
public function __construct(MessageBag $messageBag)
{
parent::__construct('The given data was invalid.');
$this->messageBag = $messageBag;
}
/**
* @return MessageBag
*/
public function errors()
{
return $this->messageBag;
}
/**
* @return string
*/
public function first()
{
return $this->messageBag->first();
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray(): array
{
return [
'error' => 'validation_exception',
'error_description' => $this->errors()
];
}
/**
* Convert the object to its JSON representation.
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{
return json_encode($this->toArray(), $options);
}
}
<?php
declare(strict_types=1);
/**
* Created by PhpStorm.
* User: zero
* Date: 2020/2/5
* Time: 16:16
*/
namespace Meibuyu\Micro\Validator\Exceptions;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;
class ValidatorExceptionHandler extends ExceptionHandler
{
public function handle(Throwable $throwable, ResponseInterface $response)
{
$this->stopPropagation(); // 阻止异常冒泡
/** @var ValidatorException $throwable */
$data = json_encode([
'code' => $throwable->getCode() ?: 401,
'msg' => $throwable->first(),
], JSON_UNESCAPED_UNICODE);
return $response
->withAddedHeader('content-type', 'application/json')
->withBody(new SwooleStream($data));
}
public function isValid(Throwable $throwable): bool
{
return $throwable instanceof ValidatorException;
}
}
\ No newline at end of file
<?php
namespace Meibuyu\Micro\Validator;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
class HyperfValidator extends AbstractValidator
{
/**
* @var ValidatorFactoryInterface
*/
protected $validator;
public function __construct(ValidatorFactoryInterface $validator)
{
$this->validator = $validator;
}
/**
* Pass the data and the rules to the validator
*
* @param string $action
* @return boolean
*/
public function passes($action = null)
{
$rules = $this->getRules($action);
$messages = $this->getMessages();
$attributes = $this->getAttributes();
$validator = $this->validator->make($this->data, $rules, $messages, $attributes);
if ($validator->fails()) {
$this->errors = $validator->errors();
return false;
}
return true;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment