Laravel 11: once() 记忆化辅助函数
once()
函数最初的灵感来自 Taylor Otwell 的这条推文,Spatie 将其制作成一个包,现在已进入Laravel 11 中的 Laravel 框架的核心。
这个辅助函数确保无论调用对象方法多少次,都能获得相同的值。当您有一些代码想要确保只运行一次时,once函数非常有用。
让我们使用新的 Laravel 11 make:class
Artisan 命令来演示它的工作原理:
php artisan make:class OnceDemo
以下是演示代码说明记忆化的工作方式:
<?php
namespace App;
use Illuminate\Support\Str;
use Ramsey\Uuid\UuidInterface;
class OnceDemo
{
public function uuid(): UuidInterface
{
return Str::uuid();
}
public function uuidOnce(): UuidInterface
{
return once(fn (): UuidInterface => $this->uuid());
}
}
如果不使用 once()
辅助函数运行如下代码,你在每次方法调用时,都会获得一个新的 UUID:
$demo = new App\OnceDemo;
foreach (range(1,5) as $_) {
echo $demo->uuid() . "\n";
}
/*
9ee5dc3c-f34b-4424-827d-13b662bb0ce1
ad9cca9d-4e98-4307-994c-c610df7c70ac
d642bc9e-d8bb-4bfe-a647-78b555b22e1c
7968b5f2-80f4-40de-95e0-e1f576c37e60
78b69cbb-07b3-45a4-b77b-edefb16f2782
*/
不过,如果通过 once()
辅助函数调用同样的代码,那么每一次都会得到相同结果:
$demo = new App\OnceDemo;
foreach (range(1,5) as $_) {
echo $demo->uuidOnce() . "\n";
}
/*
5cdfa44b-5ae5-4b0f-8a6f-4b167307fa05
5cdfa44b-5ae5-4b0f-8a6f-4b167307fa05
5cdfa44b-5ae5-4b0f-8a6f-4b167307fa05
5cdfa44b-5ae5-4b0f-8a6f-4b167307fa05
5cdfa44b-5ae5-4b0f-8a6f-4b167307fa05
*/
在我们的演示示例中,此方法将始终返回相同的对象实例,你可以验证此行为:
$demo = new App\OnceDemo;
foreach (range(1,5) as $_) {
echo spl_object_id($demo->uuidOnce()) . "\n";
}
/*
5075
5075
5075
5075
5075
*/
运行测试时,必须在每次测试后清除记忆功能,以确保在原始状态下工作。Laravel 在基本 TestCase 类中使用 Once::flush();
方法。