为什么 validate() 方法可以通过 request() 访问?

Why is validate() method accessible via request()?

引用 Laravel documentation:

By default, Laravel's base controller class uses a ValidatesRequests trait which provides a convenient method to validate incoming HTTP request with a variety of powerful validation rules

确实如此,阅读代码,App\Http\Controllers\Controller 实际上使用了 ValidatesRequests 特征。 ValidatesRequests 有一个 validate 方法。

对我来说真正奇怪的是,在文档的其他任何地方,validate 方法都是在 $request 对象上调用的。它是这样工作的。我可以使用以下代码验证表单:

public function store()
{
    $attributes = request()->validate([
        'name' => 'required|string|max:255',
    ]);
    // ...
}

但是我没有看到请求 class 上存在任何验证方法。只是文件开头的一个奇怪的注释行:

/**
 * @method array validate(array $rules, array $messages = [], array $customAttributes = [])
 */

所以有两件事:

我的实际问题是:

如果我通过 $request 对象使用 validate 方法,我从文档中粘贴的初始引用是否仍然正确?如果是这样,它是如何工作的?

"strange comment" 是 removed a couple days ago

我相信 RequestFoundationServiceProvider.php. See this article 中的 Request::macro('validate', ...) 调用中获取其 validate 函数以获得更多关于宏的信息。

好吧,validate 方法在那里,但它不直接在 FormRequest 中,而是在 ValidatesWhenResolvedTrait 特性中,因此它在 FormRequest 中可以毫无问题地使用,因此文档很好。

让我们看看这个特质的开头:

trait ValidatesWhenResolvedTrait
{
    /**
     * Validate the class instance.
     *
     * @return void
     */
    public function validate()
    {
        $this->prepareForValidation();

        $instance = $this->getValidatorInstance();

        if (! $this->passesAuthorization()) {
            $this->failedAuthorization();
        } elseif (! $instance->passes()) {
            $this->failedValidation($instance);
        }
    }

所以当你在控制器中 运行 时:

request()->validate

你是 运行 trait 的方法,ValidatesRequests 与此没有任何共同之处。

或者,如果您想使用 "Controller way" 验证,您可以这样做:

$this->validate(request(), [
        'name' => 'required|string|max:255',
    ]);

现在您将使用来自 ValidatesRequests 个请求的 validate 方法。

如您所见,Laravel 中有多种 运行 验证方式。我个人只使用表单请求验证。