0

是否可以转换Illuminate\Http\Request为您使用的自定义验证请求php artisan make:request MyRequest

我希望以一种方法进行验证,以便我拥有:

protected function register(Request $request)
{
   ...
   $this->userRepository->signup($request)
   ...
}

用户存储库:

public function signup(MyRequest $request)
{
    ...
}

这可能吗?我现在收到一个错误,因为需要一堂课。唯一想到的是制作一个界面,但我不确定它是否可以正常工作。

我得到的错误

类型错误:传递给 UserRepository::signup() 的参数 1 必须是 App\Http\Requests\MyRequest 的实例,给定的 Illuminate\Http\Request 的实例

4

3 回答 3

1

好吧,您可以将任何请求转换为任何其他请求,只要它从Illuminate\Http\Request.

Laravel 基本上有两种方法将一个请求转换为另一个请求。MyRequest 这里的问题是,当作为参数传递时,作为注入的一部分,它永远不会自动获取验证对象或触发验证。它也可能会遗漏消息包和错误处理程序,但您无法像 Laravel 在注入请求时那样通过初始化请求来解决任何问题。

因此,您仍然必须触发FormRequest启动特征时通常执行的所有序列(如果它扩展 FromRequest 而不是 Request),但仍然完全有可能并且只需做一些额外的工作,您就可以将任何请求转换为任何其他请求。

例如; 我正在使用此设置来调用一条路线profile/{section}/save来保存我的个人资料设置。根据$section's 的值,我将给定的值转换为我对该特定值的$Request任何自定义表单请求$section


use App\Http\Requests\MyRequest;
use Illuminate\Http\Request;

...

public function someControllerMethod(Request $Request) {
   $MyRequest = MyRequest::createFrom($Request);
   // .. or
   $MyRequest = MyRequest::createFromBase($Request);
}

...

因此,为了让人们开始使用 aFormRequest作为示例,基本上就是这样。

不要从 default 扩展所有自定义请求,而是使用扩展自Illuminate\Foundation\Http\FormRequest的基类FormRequest并添加自定义方法来转换和引导请求,就好像它作为参数传递一样。

namespace App\Http\Requests;

use Illuminate\Routing\Redirector;
use Illuminate\Foundation\Http\FormRequest;

class BaseFormRequest extends FormRequest {
   public function convertRequest(string $request_class) : BaseFormRequest {
      $Request = $request_class::createFrom($this);

      $app = app();
      $Request
        ->setContainer($app)
        ->setRedirector($app->make(Redirector::class));

      $Request->prepareForValidation();
      $Request->getValidatorInstance();

      return $Request;
   }

    public function authorize() {
        return true;
    }

    public function rules() {
        return [];
    }
}

让您的所有自定义FormRequest扩展您的BaseFormRequest

namespace App\Http\Requests;

class MyRequest extends BaseFormRequest {
  ...
}

现在,在您想要convert请求的任何地方,在您的控制器方法中使用基类,并使用convertRequest您希望转换的自定义请求类来转换它。

public function someControllerMethod(BaseFormRequest $Request) {
  $MyRequest = $Request->convertRequest(MyRequest::class);
}
于 2020-08-21T22:14:38.563 回答
0

是的,这没有问题,您应该创建:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class MyRequest extends FormRequest
{
   public function rules() {
       // here you put rules
   }
}

在你的控制器中:

public function signup(\App\Http\Requests\MyRequest $request)
{
    ...
}

请注意,您还应该调整authorize请求类中的方法(根据用户访问返回 true 或 false)

编辑

更新后-您应该在控制器和存储库中键入提示您的自定义类-由您决定-我经常使用 generic Illuminate\Http\Request,因此您应该这样做:

在控制器中:

public function controllerMethod(\App\Http\Requests\MyRequest $request)

在存储库中:

public function signup(\App\Http\Requests\MyRequest $request)

或者

public function signup(\Illuminate\Http\Request $request)

所以总结一下,你应该在控制器中使用表单请求类——这是进行验证的地方,以后你可以使用相同的类或通用\Illuminate\Http\Request的——我个人经常在存储库或服务中使用,\Illuminate\Http\Request因为它们通常不关心其他放入MyRequest类的东西 - 他们只想从请求类中获取数据,仅此而已。

于 2017-12-18T09:10:53.793 回答
0

我发现即使我的自定义类扩展了我也没有可能做我想做的事,Request因为自然一种方法需要一个类的实例而获得另一个类。

也许可以提取一个接口并包装和绑定它,但在我看来这将是一个快速修复。

我的观点是,我的这个概念从一开始就是错误的,它更像是一个架构问题,所以我将我的应用程序转换为一种不同的方法,并首先设法避免此类问题。

于 2017-12-21T08:49:56.040 回答