手动抛出 Laravel ValidationException VS FormRequestValidationException
Manually throw Laravel ValidationException VS FormRequestValidationException
当我手动抛出 ValidationException
和当 ValidationException
被 laravel 从 FormRequest 抛出 时有什么不同吗.
以下代码将解决问题
UserController.php
public function checkEmailExists(Request $request){
try {
$validation = Validator::make($request->only('email'), [
'email' => 'required|email|exists:users,email',
]);
if ($validation->fails()) {
throw (new ValidationException($validation));
}
} catch (\Exception $exception){
return $exception->render(); //nothing is returned/displayed
}
}
Handler.php
public function render($request, Throwable $exception)
{
dd($exception instanceof Exception);
}
从 UserController
我正在抛出 ValidationException
手动 并且在 Handler.php
渲染方法中我正在检查 $exception
是Exception
的实例。
所以如果我抛出 ValidationException manually
那么
dd($exception instanceof Exception); //gives false
但是当我使用 UserStoreRequest (FormRequest)
UserController.php
public function checkEmailExists(UserStoreRequest $request){
//Exception thrown by laravel if validation fails fro UserStoreRequest
}
然后在Handler.php render()
方法
dd($exception instanceof Exception); //gives true
1:- 为什么当我手动抛出 ValidationException 时和 laravel 从 FormRequest 抛出 ValidationException 时它有不同的行为?
2:- 如果我手动抛出 ValidationException,那么在 catch 块中我会收到以下错误
Error {#3627
#message: "Call to undefined method Illuminate\Validation\ValidationException::render()"
#code: 0
#file: "myproject/app/Http/Controllers/UserController.php"
#line: 33
dd($exception instanceof Exception); //gives false
我很确定这是不可能的。 Illuminate\Validation\ValidationException
直接扩展自 Exception
。您的结果可能与 checkEmailExists
中的 catch 块有关。正如您所知,您不必在控制器中捕获此类异常,因为这就是异常处理程序的用途 (app/Exceptions/Handler.php
).
你如何使用它不应该有任何不同的行为,所以让我展示你将如何使用这种验证:
控制器函数内部
在控制器内部你有可用的助手$this->validate(...)
:
public function index(\Illuminate\Http\Request $request) {
$this->validate($request, [
'test' => 'required|integer'
], [
'test.integer' => 'Some custom message for when this subvalidation fails'
]);
}
这会自动抛出一个 ValidationException
,因此应该被您的异常处理程序接收到。然后,您的异常处理程序将决定是否 return 带有验证错误的 JSON 响应(例如,当使用 header Accept: application/json
时会发生这种情况)或向session 这样您就可以在模板中显示它们。
外部控制者
有时,对 运行 控制器之外的事物使用验证非常方便。例如,这些可以是作业或后台任务。在那些情况下,你会这样称呼它(它基本上就是控制器函数中发生的事情):
class SomeLibrary
{
public function doSomething() {
// Quickest way:
\Illuminate\Support\Facades\Validator::make($data, [
'test' => 'required|integer'
])->validate();
// Convoluted way:
// (see your own code in the original post)
}
}
这个语法基本上做了同样的事情,并且抛出一个 ValidationException
.
立即抛出验证错误
最后,在某些情况下你想立即抛出验证异常而不需要测试任何输入,在这种情况下你可以使用它来设置错误消息:
throw \Illuminate\Validation\ValidationException::withMessages([
'amount' => 'The amount is not high enough'
]);
这将通过异常处理程序遵循相同的路线。
当我手动抛出 ValidationException
和当 ValidationException
被 laravel 从 FormRequest 抛出 时有什么不同吗.
以下代码将解决问题
UserController.php
public function checkEmailExists(Request $request){
try {
$validation = Validator::make($request->only('email'), [
'email' => 'required|email|exists:users,email',
]);
if ($validation->fails()) {
throw (new ValidationException($validation));
}
} catch (\Exception $exception){
return $exception->render(); //nothing is returned/displayed
}
}
Handler.php
public function render($request, Throwable $exception)
{
dd($exception instanceof Exception);
}
从 UserController
我正在抛出 ValidationException
手动 并且在 Handler.php
渲染方法中我正在检查 $exception
是Exception
的实例。
所以如果我抛出 ValidationException manually
那么
dd($exception instanceof Exception); //gives false
但是当我使用 UserStoreRequest (FormRequest)
UserController.php
public function checkEmailExists(UserStoreRequest $request){
//Exception thrown by laravel if validation fails fro UserStoreRequest
}
然后在Handler.php render()
方法
dd($exception instanceof Exception); //gives true
1:- 为什么当我手动抛出 ValidationException 时和 laravel 从 FormRequest 抛出 ValidationException 时它有不同的行为?
2:- 如果我手动抛出 ValidationException,那么在 catch 块中我会收到以下错误
Error {#3627
#message: "Call to undefined method Illuminate\Validation\ValidationException::render()"
#code: 0
#file: "myproject/app/Http/Controllers/UserController.php"
#line: 33
dd($exception instanceof Exception); //gives false
我很确定这是不可能的。 Illuminate\Validation\ValidationException
直接扩展自 Exception
。您的结果可能与 checkEmailExists
中的 catch 块有关。正如您所知,您不必在控制器中捕获此类异常,因为这就是异常处理程序的用途 (app/Exceptions/Handler.php
).
你如何使用它不应该有任何不同的行为,所以让我展示你将如何使用这种验证:
控制器函数内部
在控制器内部你有可用的助手$this->validate(...)
:
public function index(\Illuminate\Http\Request $request) {
$this->validate($request, [
'test' => 'required|integer'
], [
'test.integer' => 'Some custom message for when this subvalidation fails'
]);
}
这会自动抛出一个 ValidationException
,因此应该被您的异常处理程序接收到。然后,您的异常处理程序将决定是否 return 带有验证错误的 JSON 响应(例如,当使用 header Accept: application/json
时会发生这种情况)或向session 这样您就可以在模板中显示它们。
外部控制者
有时,对 运行 控制器之外的事物使用验证非常方便。例如,这些可以是作业或后台任务。在那些情况下,你会这样称呼它(它基本上就是控制器函数中发生的事情):
class SomeLibrary
{
public function doSomething() {
// Quickest way:
\Illuminate\Support\Facades\Validator::make($data, [
'test' => 'required|integer'
])->validate();
// Convoluted way:
// (see your own code in the original post)
}
}
这个语法基本上做了同样的事情,并且抛出一个 ValidationException
.
立即抛出验证错误
最后,在某些情况下你想立即抛出验证异常而不需要测试任何输入,在这种情况下你可以使用它来设置错误消息:
throw \Illuminate\Validation\ValidationException::withMessages([
'amount' => 'The amount is not high enough'
]);
这将通过异常处理程序遵循相同的路线。