Files
hyperf_data/extend/Aether/PHP/Hyperf/AetherValidator.php
Aether 0920cef866 init
2025-09-18 10:46:54 +08:00

134 lines
3.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace Aether;
use Aether\Exception\ValidationFailedException;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Validator;
use Hyperf\Context\ApplicationContext;
abstract class AetherValidator
{
#[Inject]
protected ValidatorFactoryInterface $validationFactory;
/**
* 当前场景名
*/
public ?string $currentScene = null;
/**
* 待验证数据
*/
protected array $data = [];
/**
* 自定义验证规则子类可通过该属性注册无需重写registerRules
* 格式:['规则名' => 闭包/类方法]
*/
protected array $customRules = [];
/**
* 静态快捷验证方法(简化调用)
*/
public static function validate(string $scene, array $data = []): array
{
// return (new static())->scene($scene, $data)->check();
// 从容器中获取当前类的实例(确保依赖注入生效)
$instance = ApplicationContext::getContainer()->get(static::class);
return $instance->scene($scene, $data)->check();
}
/**
* 设置验证场景和数据(支持链式调用)
*/
public function scene(string $scene, array $data = []): self
{
$this->currentScene = $scene;
$this->data = $data;
return $this;
}
/**
* 执行验证(失败抛出异常)
*/
public function check(): array
{
if (empty($this->currentScene)) {
throw new \RuntimeException('请先设置验证场景');
}
$scenes = $this->scenes();
if (!isset($scenes[$this->currentScene])) {
throw new \RuntimeException("验证场景不存在:{$this->currentScene}");
}
$sceneConfig = $scenes[$this->currentScene];
return $this->validateData(
$this->data,
$sceneConfig['rules'],
$sceneConfig['messages'] ?? [],
$sceneConfig['attributes'] ?? []
);
}
/**
* 实际执行验证的逻辑(重命名方法名更清晰)
*/
protected function validateData(array $data, array $rules, array $messages = [], array $attributes = []): array
{
$validator = $this->validationFactory->make($data, $rules, $messages, $attributes);
$this->registerRules($validator);
if ($validator->fails()) {
throw new ValidationFailedException(
$validator,
$this->currentScene ?? '',
$validator->errors()->first()
);
}
return $validator->validated();
}
/**
* 格式化验证错误信息(统一格式,供异常处理器复用)
*/
public function formatValidationErrors(Validator $validator): array
{
$errors = [];
$failedRules = $validator->failed();
$errorMessages = $validator->errors()->getMessages();
$attributes = $validator->attributes();
foreach ($failedRules as $field => $rules) {
$errors[] = [
'field' => $field,
'field_label' => $attributes[$field] ?? $field,
'message' => $errorMessages[$field][0] ?? '',
'rules' => array_keys($rules),
'value' => $validator->getValue($field)
];
}
return $errors;
}
/**
* 自动注册自定义规则(优先使用$customRules属性
*/
protected function registerRules(Validator $validator): void
{
foreach ($this->customRules as $ruleName => $rule) {
$validator->extend($ruleName, $rule);
}
}
/**
* 定义场景验证规则(子类实现)
*/
abstract protected function scenes(): array;
}