26日1846-Validator使用方式修复.md 5.3 KB

Validator使用方式修复

任务时间: 2025年05月26日 18:46
任务类型: Bug修复
涉及模块: Pet, Farm

问题描述

Pet/GetHandler出现错误:

The validator [App\Module\Pet\Validators\PetGetValidator] don't exists!

问题分析

通过分析错误日志和代码,发现问题出现在Validation类中使用自定义Validator的方式不正确。

错误的使用方式

在PetGetValidation和FertilizerValidation中,我使用了类名字符串的方式:

// 错误的方式
[
    'item_id', PetGetValidator::class, 'args' => ['user_id'],
    'msg' => '宠物获取验证失败'
]

正确的使用方式

通过查看其他工作的Validation类(如CropPlantValidation、CropHarvestValidation等),发现正确的使用方式是实例化Validator对象:

// 正确的方式
[
    'item_id', new PetGetValidator($this, ['user_id']),
    'msg' => '宠物获取验证失败'
]

根本原因

验证框架(inhere/php-validate)在处理自定义Validator时,期望的是:

  1. 内置验证器名称(字符串)
  2. 函数名(字符串)
  3. Validator实例对象

当使用ValidatorClass::class时,框架无法识别这是一个自定义Validator类,导致抛出"don't exists"错误。

修复方案

1. 修复PetGetValidation

文件: app/Module/Pet/Validations/PetGetValidation.php

修复前:

[
    'item_id', PetGetValidator::class, 'args' => ['user_id'],
    'msg' => '宠物获取验证失败'
]

修复后:

[
    'item_id', new PetGetValidator($this, ['user_id']),
    'msg' => '宠物获取验证失败'
]

2. 修复FertilizerValidation

文件: app/Module/Farm/Validations/FertilizerValidation.php

修复前:

[
    'land_id', LandOwnershipValidator::class, 'args' => ['user_id', 'land'],
    'msg' => '土地不存在或不属于当前用户'
],
[
    'item_id', ItemOwnershipValidator::class, 'args' => ['user_id', 'instance_id', 'quantity'],
    'msg' => '您没有该肥料物品'
],
[
    'item_id', FertilizerItemValidator::class, 'args' => ['fertilizer_item', 'crop_growth_time'],
    'msg' => '该物品不是有效的肥料'
],
[
    'land_id', FertilizerUsageValidator::class, 'args' => ['land', 'crop'],
    'msg' => '当前土地状态或作物生长阶段不允许使用肥料'
]

修复后:

[
    'land_id', new LandOwnershipValidator($this, ['user_id', 'land']),
    'msg' => '土地不存在或不属于当前用户'
],
[
    'item_id', new ItemOwnershipValidator($this, ['user_id', 'instance_id', 'quantity']),
    'msg' => '您没有该肥料物品'
],
[
    'item_id', new FertilizerItemValidator($this, ['fertilizer_item', 'crop_growth_time']),
    'msg' => '该物品不是有效的肥料'
],
[
    'land_id', new FertilizerUsageValidator($this, ['land', 'crop']),
    'msg' => '当前土地状态或作物生长阶段不允许使用肥料'
]

技术细节

Validator构造函数

自定义Validator继承自UCore\Validator,其构造函数签名为:

public function __construct(public ValidationCore $validation, public array $args = [], public $message = '')

参数说明:

  • $validation: 验证对象实例,用于设置验证结果和错误信息
  • $args: 参数数组,传递给Validator的配置参数
  • $message: 可选的错误消息

验证框架处理逻辑

验证框架在处理验证规则时:

  1. 字符串类型: 查找内置验证器或函数
  2. 对象类型: 直接调用对象的验证方法
  3. 类名字符串: 无法识别,抛出"don't exists"错误

最佳实践

  1. 使用实例化方式: 总是使用new ValidatorClass($this, $args)
  2. 参数传递: 通过构造函数的$args参数传递配置
  3. 错误处理: 在Validator中使用$this->addError()添加错误信息
  4. 数据设置: 使用$this->validation->$property = $value设置验证结果

预防措施

1. 代码规范

  • 统一使用实例化方式创建Validator
  • 在代码审查中检查Validator使用方式
  • 添加IDE提示和文档说明

2. 测试覆盖

  • 为每个Validation类添加单元测试
  • 测试验证成功和失败的情况
  • 验证错误消息的正确性

3. 文档更新

  • 更新Validation使用文档
  • 提供正确的示例代码
  • 说明常见错误和解决方案

影响范围

修复的问题

  1. Pet/GetHandler: 解决了宠物获取验证失败的问题
  2. FertilizerHandler: 确保施肥验证能够正常工作
  3. 验证一致性: 统一了Validator的使用方式

潜在风险

  1. 低风险: 修复是向正确方向的改进
  2. 兼容性: 不影响现有功能
  3. 性能: 对性能无负面影响

完成状态

  • 修复 PetGetValidation 中的 Validator 使用方式
  • 修复 FertilizerValidation 中的 Validator 使用方式
  • 验证修复效果
  • 代码提交和推送

总结

本次修复解决了Validator使用方式不正确导致的运行时错误。通过将类名字符串改为实例化对象,确保了验证框架能够正确识别和调用自定义Validator。

这个问题提醒我们在使用第三方验证框架时,需要严格按照框架的API规范来使用,避免因为使用方式不当导致的运行时错误。

修复后,Pet/GetHandler和FertilizerHandler的验证逻辑都能正常工作,提高了系统的稳定性和可靠性。