【问题标题】:The passes() function of custom validation rule is ignored自定义验证规则的 pass() 函数被忽略
【发布时间】:2019-09-10 18:15:43
【问题描述】:

我不知道是我睡眠不足还是遗漏了一些明显的东西,但我遇到了这个问题:我创建了一个自定义验证规则,我需要通过构造函数传递一个请求值来执行验证.

这是我的设置:

自定义验证规则

/** Rules/RouteValidationRule.php */

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class RouteValidationRule implements Rule {

    private $action;

    public function __construct(string $action)
    {
        $this->action = $action; // doing dd($action) output the correct value.
    }

    // a dd('Hi'); inside here is just ignored:
    public function passes($attribute, $value)
    {
        if ($this->action === 'complete')
            return (isset($value['delivery_route']))
                && (count($value['delivery_route']) >= 2);
        else
            return true;
    }

    public function message() { /** */ }
}

表单请求

/** UpdateOrderRequest.php */

namespace App\Http\Requests;

use App\Rules\OrderStatusesRule;
use App\Rules\RouteValidationRule;
use Illuminate\Foundation\Http\FormRequest;

class UpdateOrderRequest extends FormRequest {

    public function authorize() { /** */ }

    public function rules() 
    {
        return [
            'action' => ['required', new OrderStatusesRule],
            'meta.delivery_route' => [
                'array',
                new RouteValidationRule($this->get('action')), // <---
           ],
        ];
    }
}

但问题是,该值正在到达自定义规则构造函数,但它没有到达 passes() 方法,它只是忽略了这一点并继续进行,就好像这没问题一样。

PD:我已经用dd()检查了每一步。

提前致谢。


更新

/** MyController.php */

    /**
     * @param UpdateOrderRequest $request
     * @return mixed
     */
    public function handle(UpdateOrderRequest $request) // the RequestForm is injected
    {
        dd('I passed');  // <-- is reaching this statement when it shouldn't
    }

【问题讨论】:

  • 你也可以粘贴控制器处理方法吗?也可能是您的请求验证在上一步失败,因此由于快速退出策略而无法达到您的验证规则?
  • @Tacsiazuma 就是这样,它正在通过验证并到达控制器。我会按照建议添加相关代码。
  • 如果您检查控制器中的请求,它是否包含提到的字段?如果添加“必需”作为规则会发生什么?
  • @Tacsiazuma 如果我在该属性中添加required 作为规则,它会在丢失时失败(如预期的那样)但是当我添加参数并重做请求时,它通过required 但忽略passes() 自定义规则。是的,属性到达控制器,这真的很奇怪

标签: php laravel validation laravel-5.8


【解决方案1】:

您的规则无法运行的原因是您正在测试的属性不在Request 中或为空。如果您希望规则无论是否存在都运行,请让您的规则实施 ImplicitRule 而不是 Rule 例如:

class RouteValidationRule implements ImplicitRule {

【讨论】:

    【解决方案2】:

    我拼凑了一个类似的解决方案,发现如果要验证的字段不存在,它只会忽略验证(除非还添加了需要作为验证规则):

    Route::any('/', function (UpdateOrderRequest $orderRequest) {
        dd($orderRequest);
    });
    

    我在 pass 方法中添加了一个 dd('pass'):

     public function passes($attribute, $value)
        {
            dd('pass');
            if ($this->action === 'complete')
                return (isset($value['delivery_route']))
                    && (count($value['delivery_route']) >= 2);
            else
                return true;
        }
    

    然后用邮递员发送请求:

    POST / HTTP/1.1
    Host: localhost:8888
    Content-Type: application/json
    cache-control: no-cache
    Postman-Token: 848f7181-2c28-46a5-b508-4cb35083315e
    {
        "action" : "something",
        "meta" : {
            "delivery_route" : "something else"
        }
    }------WebKitFormBoundary7MA4YWxkTrZu0gW--
    

    它遇到了 pass 方法并回显了“pass”。然后我重命名了上面的“delivery_route”,它最终在控制器中。

    来自 Laravel 验证文档:

    默认情况下,当正在验证的属性不存在或 包含一个空字符串,正常的验证规则,包括自定义 扩展,未运行。

    【讨论】:

    • 我没有得到这个解决方案,或者它是不是我的问题的确认? (可能是一个错误)
    • 我确实将属性设置为一个值,该值应该会破坏验证但仍然通过。
    • 因为字段名称不匹配我猜。阅读 laravel.com/docs/5.8/validation 中的隐式扩展
    • 我用相同的属性名称提出了一个请求,说实话,真的很奇怪。
    • 您可以尝试使用 JSON 请求(如果还没有的话)并使用请求正文更新您的问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    相关资源
    最近更新 更多