如果规则失败,Laravel $validator->validated()
方法应该抛出一个异常,但是当我使用一个正在进行验证的值数组并结合了一个定制的验证规则时,没有抛出异常.
因此,我在routes/api.php文件中有以下示例:
<?php
use App\Rules\Uppercase;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Validator;
Route::get('/validation', function () {
$data = [
'name' => 'testname',
'environments' => [
'testenv1',
'testenv2',
]
];
$validator = Validator::make($data, [
'name' => ['required', 'string', 'min:5', 'max:255'],
'environments' => [
'required',
'nullable',
'array',
new Uppercase
]
]);
try {
$validator->validated();
} catch (Exception $e) {
dd('caught by the exception thrown', $e->validator->failed());
}
dd('nothing happened');
})->name('validation');
现在,当我运行上面的用例,而不是像我预期的那样接收到ValidationException异常时,因为我提供的环境数据都是小写的,所以会显示"Nothing Happen"字符串.
我使用的自定义验证规则是Laravel文档大写规则的修改版本,以支持一组值,而不仅仅是一个字符串->;https://laravel.com/docs/10.x/validation#custom-validation-rules 实际的大写自定义验证规则如下所示:
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Translation\PotentiallyTranslatedString;
class Uppercase implements ValidationRule
{
/**
* Run the validation rule.
*
* @param Closure(string): PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
foreach ($value as $index => $item) {
if (strtoupper($item) !== $item) {
$fail('The :attribute must be uppercase.');
}
}
}
}
更深入地研究,我发现$validator->validated()
方法判断以决定是否抛出异常的第一件事是$validator->invalid()
方法,而该方法又包含以下行:
$failed = Arr::only(Arr::dot($invalid), array_keys($this->failed()));
,并且通过使用Arr::dot($invalid)
而不是普通的$invalid
数组,它会错过环境大写验证错误.
在我看来,这是一种错误的行为.
如果我遗漏了什么,请告诉我好吗?