Laravel 形成 returns "The given data is invalid" 而我发送替代错误消息
Laravel form returns "The given data is invalid" while I send alternative error messages
我正在一个项目中使用 Laravel 6(包含在这个聊天系统/项目中)。
第一次如此寻找一些东西。
使用带有 PHPStorm 的 xdebug 的调试功能,我可以完美地遵循它。
这是我看到的:
注册控制器:
protected function validator(array $data)
{
$data['name'] = htmlspecialchars($data['name']);
return Validator::make($data, [
'name' => ['required', 'string', 'max:100'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users', 'regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/'],
'password' => ['required', 'string', 'min:3', 'max:30', 'confirmed', new NoSpaceContaine()],
'min18years' => ['accepted'],
'accept_all_agreements' => ['accepted'],
'medical1' => ['accepted'],
'medical2' => ['accepted']
], [
'name.required' => 'A name is required',
'email.required' => 'An email is required',
'password.required' => 'A password is required',
'min18years.accepted' => 'An approval for min 18 years is required',
'accept_all_agreements.accepted' => 'An approval for agreements is required',
'medical1.accepted' => 'An approval for medical1 is required',
'medical2.accepted' => 'An approval for medical2 is required'
]);
}
$Data(来自调试器,故意未选中 min18years 复选框):
$data = {array} [9]
_token = "oEMQFjasGoex4MDiThonh8Vw0e5UbyQ5o7GTRAi8"
name = "Peter7"
email = "my7@email.here"
password = "123"
password_confirmation = "123"
min18years = "0"
accept_all_agreements = "yes"
medical1 = "yes"
medical2 = "yes"
Illuminate\Validation\Validator.php:"
public function validate()
{
if ($this->fails()) {
throw new ValidationException($this);
}
return $this->validated();
}
get抛出错误,调用“ValidationException”时的当前数据:
$这个:
$this = {Illuminate\Validation\Validator} [27]
translator = {Illuminate\Translation\Translator} [7]
container = {Illuminate\Foundation\Application} [33]
presenceVerifier = {Illuminate\Validation\DatabasePresenceVerifier} [2]
failedRules = {array} [1]
min18years = {array} [1]
Accepted = {array} [0]
excludeAttributes = {array} [0]
messages = {Illuminate\Support\MessageBag} [2]
messages = {array} [1]
min18years = {array} [1]
0 = "An approval for min 18 years is required"
format = ":message"
data = {array} [9]
_token = "oEMQFjasGoex4MDiThonh8Vw0e5UbyQ5o7GTRAi8"
name = "Peter7"
email = "my7@email.here"
password = "123"
password_confirmation = "123"
min18years = "0"
accept_all_agreements = "yes"
medical1 = "yes"
medical2 = "yes"
initialRules = {array} [7]
rules = {array} [7]
currentRule = "accepted"
implicitAttributes = {array} [0]
implicitAttributesFormatter = null
distinctValues = {array} [0]
after = {array} [0]
customMessages = {array} [7]
name.required = "A name is required"
email.required = "An email is required"
password.required = "A password is required"
min18years.accepted = "An approval for min 18 years is required"
accept_all_agreements.accepted = "An approval for agreements is required"
medical1.accepted = "An approval for medical1 is required"
medical2.accepted = "An approval for medical2 is required"
但是当我跟随对\Illuminate\Validation\ValidationException的调用时。php:
public function __construct($validator, $response = null, $errorBag = 'default')
{
parent::__construct('The given data was invalid.');
$this->response = $response;
$this->errorBag = $errorBag;
$this->validator = $validator;
}
$this 没有收到传递给该函数的消息。
$这个:
$this = {Illuminate\Validation\ValidationException} [12]
validator = null
response = null
status = {int} 422
errorBag = null
redirectTo = null
message = ""
*Exception*string = ""
code = {int} 0
file = "C:\Sources\wachtweken.nl\vendor\laravel\framework\src\Illuminate\Validation\Validator.php"
line = {int} 386
*Exception*trace = {array} [44]
*Exception*previous = null
我希望在执行调试步骤时可以清楚这一点...
按要求添加了验证器函数(但这是默认的:
protected function validator(array $data)
{
$data['name'] = htmlspecialchars($data['name']);
return Validator::make($data, [
'name' => ['required', 'string', 'max:100'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users', 'regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/'],
'password' => ['required', 'string', 'min:3', 'max:30', 'confirmed', new NoSpaceContaine()],
'min18years' => ['accepted'],
'accept_all_agreements' => ['accepted'],
'medical1' => ['accepted'],
'medical2' => ['accepted']
], [
'name.required' => 'A name is required',
'email.required' => 'An email is required',
'password.required' => 'A password is required',
'min18years.accepted' => 'An approval for min 18 years is required',
'accept_all_agreements.accepted' => 'An approval for agreements is required',
'medical1.accepted' => 'An approval for medical1 is required',
'medical2.accepted' => 'An approval for medical2 is required'
]);
}
来自更深层控制器的完整代码:
Post论坛的功能在这里:
RegisterController.php:注册
/**
* @param Request $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function register(Request $request)
{
try {
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
} catch (Exception $e) {
return Redirect::back()->withInput()->withErrors(['error' => $e->getMessage()]);
}
}
Illuminate\Validation\Factory
class Validator {
/**
* Create a new Validator instance.
*
* @param array $data
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return \Illuminate\Validation\Validator
* @static
*/
public static function make($data, $rules, $messages = [], $customAttributes = [])
{
/** @var \Illuminate\Validation\Factory $instance */
return $instance->make($data, $rules, $messages, $customAttributes);
}
/**
* Validate the given data against the provided rules.
*
* @param array $data
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return array
* @throws \Illuminate\Validation\ValidationException
* @static
*/
public static function validate($data, $rules, $messages = [], $customAttributes = [])
{
/** @var \Illuminate\Validation\Factory $instance */
return $instance->validate($data, $rules, $messages, $customAttributes);
}
/**
* Register a custom validator extension.
*
* @param string $rule
* @param \Closure|string $extension
* @param string|null $message
* @return void
* @static
*/
异常是触发器,它转到
Illuminate\Validation\ValidationException:
<?php
namespace Illuminate\Validation;
use Exception;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
class ValidationException extends Exception
{
/**
* The validator instance.
*
* @var \Illuminate\Contracts\Validation\Validator
*/
public $validator;
/**
* The recommended response to send to the client.
*
* @var \Symfony\Component\HttpFoundation\Response|null
*/
public $response;
/**
* The status code to use for the response.
*
* @var int
*/
public $status = 422;
/**
* The name of the error bag.
*
* @var string
*/
public $errorBag;
/**
* The path the client should be redirected to.
*
* @var string
*/
public $redirectTo;
/**
* Create a new exception instance.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @param \Symfony\Component\HttpFoundation\Response|null $response
* @param string $errorBag
* @return void
*/
public function __construct($validator, $response = null, $errorBag = 'default')
{
parent::__construct('The given data was invalid.');
$this->response = $response;
$this->errorBag = $errorBag;
$this->validator = $validator;
}
/**
* Create a new validation exception from a plain array of messages.
*
* @param array $messages
* @return static
*/
public static function withMessages(array $messages)
{
return new static(tap(ValidatorFacade::make([], []), function ($validator) use ($messages) {
foreach ($messages as $key => $value) {
foreach (Arr::wrap($value) as $message) {
$validator->errors()->add($key, $message);
}
}
}));
}
/**
* Get all of the validation error messages.
*
* @return array
*/
public function errors()
{
return $this->validator->errors()->messages();
}
/**
* Set the HTTP status code to be used for the response.
*
* @param int $status
* @return $this
*/
public function status($status)
{
$this->status = $status;
return $this;
}
/**
* Set the error bag on the exception.
*
* @param string $errorBag
* @return $this
*/
public function errorBag($errorBag)
{
$this->errorBag = $errorBag;
return $this;
}
/**
* Set the URL to redirect to on a validation error.
*
* @param string $url
* @return $this
*/
public function redirectTo($url)
{
$this->redirectTo = $url;
return $this;
}
/**
* Get the underlying response instance.
*
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function getResponse()
{
return $this->response;
}
}
你的问题是try/catch
。您不必使用它,如果它抛出错误,它将默认 return 返回到它来自的页面 (response()->back()
) 输入 (->withInput()
) 和验证错误(errors
将被填充以供您在 blade 中使用)。
因此,将您的代码更改为:
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
再次阅读 this 部分文档,您会发现这会起作用。
我正在一个项目中使用 Laravel 6(包含在这个聊天系统/项目中)。 第一次如此寻找一些东西。 使用带有 PHPStorm 的 xdebug 的调试功能,我可以完美地遵循它。 这是我看到的:
注册控制器:
protected function validator(array $data)
{
$data['name'] = htmlspecialchars($data['name']);
return Validator::make($data, [
'name' => ['required', 'string', 'max:100'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users', 'regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/'],
'password' => ['required', 'string', 'min:3', 'max:30', 'confirmed', new NoSpaceContaine()],
'min18years' => ['accepted'],
'accept_all_agreements' => ['accepted'],
'medical1' => ['accepted'],
'medical2' => ['accepted']
], [
'name.required' => 'A name is required',
'email.required' => 'An email is required',
'password.required' => 'A password is required',
'min18years.accepted' => 'An approval for min 18 years is required',
'accept_all_agreements.accepted' => 'An approval for agreements is required',
'medical1.accepted' => 'An approval for medical1 is required',
'medical2.accepted' => 'An approval for medical2 is required'
]);
}
$Data(来自调试器,故意未选中 min18years 复选框):
$data = {array} [9]
_token = "oEMQFjasGoex4MDiThonh8Vw0e5UbyQ5o7GTRAi8"
name = "Peter7"
email = "my7@email.here"
password = "123"
password_confirmation = "123"
min18years = "0"
accept_all_agreements = "yes"
medical1 = "yes"
medical2 = "yes"
Illuminate\Validation\Validator.php:"
public function validate()
{
if ($this->fails()) {
throw new ValidationException($this);
}
return $this->validated();
}
get抛出错误,调用“ValidationException”时的当前数据:
$这个:
$this = {Illuminate\Validation\Validator} [27]
translator = {Illuminate\Translation\Translator} [7]
container = {Illuminate\Foundation\Application} [33]
presenceVerifier = {Illuminate\Validation\DatabasePresenceVerifier} [2]
failedRules = {array} [1]
min18years = {array} [1]
Accepted = {array} [0]
excludeAttributes = {array} [0]
messages = {Illuminate\Support\MessageBag} [2]
messages = {array} [1]
min18years = {array} [1]
0 = "An approval for min 18 years is required"
format = ":message"
data = {array} [9]
_token = "oEMQFjasGoex4MDiThonh8Vw0e5UbyQ5o7GTRAi8"
name = "Peter7"
email = "my7@email.here"
password = "123"
password_confirmation = "123"
min18years = "0"
accept_all_agreements = "yes"
medical1 = "yes"
medical2 = "yes"
initialRules = {array} [7]
rules = {array} [7]
currentRule = "accepted"
implicitAttributes = {array} [0]
implicitAttributesFormatter = null
distinctValues = {array} [0]
after = {array} [0]
customMessages = {array} [7]
name.required = "A name is required"
email.required = "An email is required"
password.required = "A password is required"
min18years.accepted = "An approval for min 18 years is required"
accept_all_agreements.accepted = "An approval for agreements is required"
medical1.accepted = "An approval for medical1 is required"
medical2.accepted = "An approval for medical2 is required"
但是当我跟随对\Illuminate\Validation\ValidationException的调用时。php:
public function __construct($validator, $response = null, $errorBag = 'default')
{
parent::__construct('The given data was invalid.');
$this->response = $response;
$this->errorBag = $errorBag;
$this->validator = $validator;
}
$this 没有收到传递给该函数的消息。
$这个:
$this = {Illuminate\Validation\ValidationException} [12]
validator = null
response = null
status = {int} 422
errorBag = null
redirectTo = null
message = ""
*Exception*string = ""
code = {int} 0
file = "C:\Sources\wachtweken.nl\vendor\laravel\framework\src\Illuminate\Validation\Validator.php"
line = {int} 386
*Exception*trace = {array} [44]
*Exception*previous = null
我希望在执行调试步骤时可以清楚这一点...
按要求添加了验证器函数(但这是默认的:
protected function validator(array $data)
{
$data['name'] = htmlspecialchars($data['name']);
return Validator::make($data, [
'name' => ['required', 'string', 'max:100'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users', 'regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/'],
'password' => ['required', 'string', 'min:3', 'max:30', 'confirmed', new NoSpaceContaine()],
'min18years' => ['accepted'],
'accept_all_agreements' => ['accepted'],
'medical1' => ['accepted'],
'medical2' => ['accepted']
], [
'name.required' => 'A name is required',
'email.required' => 'An email is required',
'password.required' => 'A password is required',
'min18years.accepted' => 'An approval for min 18 years is required',
'accept_all_agreements.accepted' => 'An approval for agreements is required',
'medical1.accepted' => 'An approval for medical1 is required',
'medical2.accepted' => 'An approval for medical2 is required'
]);
}
来自更深层控制器的完整代码:
Post论坛的功能在这里:
RegisterController.php:注册
/**
* @param Request $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function register(Request $request)
{
try {
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
} catch (Exception $e) {
return Redirect::back()->withInput()->withErrors(['error' => $e->getMessage()]);
}
}
Illuminate\Validation\Factory
class Validator {
/**
* Create a new Validator instance.
*
* @param array $data
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return \Illuminate\Validation\Validator
* @static
*/
public static function make($data, $rules, $messages = [], $customAttributes = [])
{
/** @var \Illuminate\Validation\Factory $instance */
return $instance->make($data, $rules, $messages, $customAttributes);
}
/**
* Validate the given data against the provided rules.
*
* @param array $data
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return array
* @throws \Illuminate\Validation\ValidationException
* @static
*/
public static function validate($data, $rules, $messages = [], $customAttributes = [])
{
/** @var \Illuminate\Validation\Factory $instance */
return $instance->validate($data, $rules, $messages, $customAttributes);
}
/**
* Register a custom validator extension.
*
* @param string $rule
* @param \Closure|string $extension
* @param string|null $message
* @return void
* @static
*/
异常是触发器,它转到 Illuminate\Validation\ValidationException:
<?php
namespace Illuminate\Validation;
use Exception;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
class ValidationException extends Exception
{
/**
* The validator instance.
*
* @var \Illuminate\Contracts\Validation\Validator
*/
public $validator;
/**
* The recommended response to send to the client.
*
* @var \Symfony\Component\HttpFoundation\Response|null
*/
public $response;
/**
* The status code to use for the response.
*
* @var int
*/
public $status = 422;
/**
* The name of the error bag.
*
* @var string
*/
public $errorBag;
/**
* The path the client should be redirected to.
*
* @var string
*/
public $redirectTo;
/**
* Create a new exception instance.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @param \Symfony\Component\HttpFoundation\Response|null $response
* @param string $errorBag
* @return void
*/
public function __construct($validator, $response = null, $errorBag = 'default')
{
parent::__construct('The given data was invalid.');
$this->response = $response;
$this->errorBag = $errorBag;
$this->validator = $validator;
}
/**
* Create a new validation exception from a plain array of messages.
*
* @param array $messages
* @return static
*/
public static function withMessages(array $messages)
{
return new static(tap(ValidatorFacade::make([], []), function ($validator) use ($messages) {
foreach ($messages as $key => $value) {
foreach (Arr::wrap($value) as $message) {
$validator->errors()->add($key, $message);
}
}
}));
}
/**
* Get all of the validation error messages.
*
* @return array
*/
public function errors()
{
return $this->validator->errors()->messages();
}
/**
* Set the HTTP status code to be used for the response.
*
* @param int $status
* @return $this
*/
public function status($status)
{
$this->status = $status;
return $this;
}
/**
* Set the error bag on the exception.
*
* @param string $errorBag
* @return $this
*/
public function errorBag($errorBag)
{
$this->errorBag = $errorBag;
return $this;
}
/**
* Set the URL to redirect to on a validation error.
*
* @param string $url
* @return $this
*/
public function redirectTo($url)
{
$this->redirectTo = $url;
return $this;
}
/**
* Get the underlying response instance.
*
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function getResponse()
{
return $this->response;
}
}
你的问题是try/catch
。您不必使用它,如果它抛出错误,它将默认 return 返回到它来自的页面 (response()->back()
) 输入 (->withInput()
) 和验证错误(errors
将被填充以供您在 blade 中使用)。
因此,将您的代码更改为:
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
再次阅读 this 部分文档,您会发现这会起作用。