编程

Laravel 11: once() 记忆化辅助函数

884 2024-02-05 02:21:00

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(); 方法。