我有 laravel FormRequest,它准备验证规则。我在最后转储了prepareForValidation 函数,它立即显示转储。但是当我尝试在控制器中调用
$request->validation()
函数时,需要很长时间。我有类似 required|numeric|max:999999.99|min:0|email
的验证。当我发送 1000 个项目时,每个项目几乎包含 45 个字段。
在我的代码端进行此验证之前没有任何操作。有什么解决办法来处理此类事情吗?请求通过 api 发送。
Laravel 验证对于大型数组来说很慢。我已向 Laravel 发送了 issue 和 PR 来修复它。我的 PR 没有被接受。 在修复 Laravel 之前你现在可以做什么:
$request->validate(['array' => 'required|array|max:100']);
$request->validate(['array.*' => 'required|numeric|max:1000']);
collect($request['array'])->chunk(100)->each(function (array $chunk) {
Validator::validate(
['array' => $chunk],
['array.*' => 'required|numeric|max:1000']);
});
Laravel 验证非常慢,维护者的官方立场是您应该做一些与验证大负载不同的事情。我认为事实更加微妙,有时对大型 HTTP 有效负载进行验证就很好。
我没有使用内置的 Laravel 验证,而是新建了 PHP 类,速度超级快。
这是一个帮助您入门的概念。差异是显着的。
<?php
declare(strict_types=1);
readonly class SpeedTest {
public function __construct(public int $room_id, public string $external_id)
{
throw_if($this->room_id < 0, new \DomainException("Example of a validation rule"));
}
}
$payload = array_map(fn($i) => ['room_id' => $i, 'external_id' => "string_{$i}"], range(1, 5000));
\Illuminate\Support\Benchmark::dd([
'validation' => fn() => \Illuminate\Support\Facades\Validator::validate([
'array' => $payload,
], [
'array.*.room_id' => 'required|integer',
'array.*.external_id' => 'required|string',
]),
'newing_up' => fn() => array_map(fn($i) => new SpeedTest(...$i), $payload)
], 1);
结果:
"validation" => "636.862ms"
"newing_up" => "15.103ms"
如果您想要 422 而不是 500,您可以捕获此代码中引发的异常并返回 422。根据您的用例,您可以省略或确保包含
declare(strict_types=1);