将请求转换为自定义验证请求

时间:2017-12-18 09:07:11

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

是否可以将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实例,实例   照亮\ Http \请求

3 个答案:

答案 0 :(得分: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)

修改

更新后 - 你应该在控制器和存储库中输入提示你的自定义类 - 这取决于你 - 我经常使用泛型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)

总而言之,你应该在控制器中使用Form请求类 - 这是进行验证的地方,之后你可以使用相同的类或通用\Illuminate\Http\Request - 我个人经常在存储库或服务中使用\Illuminate\Http\Request因为他们通常不关心放入MyRequest类的其他内容 - 他们只是想从请求类中获取数据,就是这样。

答案 1 :(得分:0)

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

也许有可能提取出一个接口并包装并绑定它,但在我看来这是一个quickfix。

我的观点是,我从一开始就认为这个概念是错误的,而且更多的是一个架构问题,所以我将我的应用转换为不同的方法,并设法首先避免这些问题。

答案 2 :(得分:0)

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

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

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

例如;我正在使用此设置仅调用一条路由profile/{section}/save来保存我的个人资料设置。根据{{​​1}}的值,我将给定的$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