【问题标题】:Transform Request to custom validation request将请求转换为自定义验证请求
【发布时间】:2018-05-31 14:19:06
【问题描述】:

是否可以将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 given

【问题讨论】:

  • 如果您将 myRequest 添加到您的控制器,这应该可以工作
  • myRequest 扩展了 Request 类,所以这应该可以工作
  • 查看我更新的问题
  • @Norgul 我已经更新了我的答案

标签: php laravel laravel-5 laravel-validation laravel-request


【解决方案1】:

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

<?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)

编辑

更新后 - 你应该在控制器和存储库中键入提示你的自定义类 - 这取决于你 - 我经常使用通用 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 - 我个人经常在存储库或服务中使用 @987654329 @ 因为他们通常不关心放在 MyRequest 类中的其他内容 - 他们只想从请求类中获取数据,仅此而已。

【讨论】:

  • 我认为您不明白我的要求。当我将 Illuminate Request 转发到将 MyRequest 作为参数的方法时出现错误
  • 这是因为你在那里传递了无效的对象。在控制器中你应该有某个地方public function controllerMethod(\App\Http\Requests\MyRequest $request) 然后在控制器方法中你可以使用:$this-&gt;userRepository-&gt;signup($request) 没有任何问题。现在您在控制器中使用 \Illuminate\Http\Request 所以它不会像我在回答中解释的那样工作
  • 我知道我在传递什么 :) 我在寻求一种可能的解决方法。我知道那些是 2 个不同的类:)
  • 没有解决方法。您不能将假设 Apple 类的对象传递给需要 Onion 类的方法 - 它不起作用。如果您不关心验证,您可以只创建没有规则的 MyRequest 类,但您需要将 MyRequest 类的对象传递给 signup 方法
  • 我认为这是可以做到的,因为 MyRequest 最终是从 Request 扩展而来的
【解决方案2】:

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

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

我的看法是,我的这个概念从一开始就是错误的,而且更多的是架构问题,因此我将我的应用程序转换为不同的方法,并设法从一开始就避免此类问题。

【讨论】:

    【解决方案3】:

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

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

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

    例如;我正在使用这个设置来调用一个路由profile/{section}/save 来保存我的配置文件设置。根据$section 的值,我将给定的$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);
    }
    
    ...
    

    所以要让人们开始使用FormRequest 作为示例,基本上就是这样。

    不要从默认 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-30
      • 2017-11-17
      • 2020-07-28
      • 1970-01-01
      • 2021-06-30
      • 2018-04-16
      • 1970-01-01
      • 2021-02-06
      • 2017-01-13
      相关资源
      最近更新 更多