once

A magic memoization function

Github星跟踪图

A magic memoization function

Latest Version on Packagist
Software License
Build Status
Quality Score
StyleCI
Total Downloads

This package contains a once function. You can pass a callable to it. Here's quick example:

class MyClass
{
    public function getNumber()
    {
        return once(function () {
            return rand(1, 10000);
        });
    }
}

No matter how many times you run (new MyClass())->getNumber() inside the same request you'll always get the same number.

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Installation

You can install the package via composer:

composer require spatie/once

Usage

The once function accepts a callable.

class MyClass
{
    public function getNumber()
    {
        return once(function () {
            return rand(1, 10000);
        });
    }
}

No matter how many times you run (new MyClass())->getNumber() you'll always get the same number.

The once function will only run once per combination of argument values the containing method receives.

class MyClass
{
    /**
     * It also works in static context!
     */
    public static function getNumberForLetter($letter)
    {
        return once(function () use ($letter) {
            return $letter . rand(1, 10000000);
        });
    }
}

So calling MyClass::getNumberForLetter('A') will always return the same result, but calling MyClass::getNumberForLetter('B') will return something else.

Flushing the cache

To flush the entire cache you can call:

Spatie\Once\Cache::flush();

Disabling the cache

In your test you probably don't want to cache values. To disable the cache you can call:

Spatie\Once\Cache::disable();

You can re-enable the cache with

Spatie\Once\Cache::enable();

Behind the curtains

Let's go over the code of the once function to learn how all the magic works.

In short: it will execute the given callable and save the result in the static $values property of Spatie\Once\Cache. When we detect that once has already run before, we're just going to return the value stored inside the $values array instead of executing the callable again.

The first thing it does is calling debug_backtrace. We'll use the output to determine in which function and class once is called and to get access to the object that function is running in. Yeah, we're already in voodoo-land. The output of the debug_backtrace is passed to a new instance of Backtrace. That class is just a simple wrapper so we can work more easily with the backtrace.

$trace = debug_backtrace(
    DEBUG_BACKTRACE_PROVIDE_OBJECT, 2
)[1];

$backtrace = new Backtrace($trace);

$object = $backtrace->getObject();

Next, we calculate a hash of the backtrace. This hash will be unique per function once was called in and the values of the arguments that function receives.

$hash = $backtrace->getHash();

Finally we will check if there's already a value stored for the given hash. If not, then execute the given $callback and store the result in Spatie\Once\Cache. In the other case just return the value from that cache (the $callback isn't executed).

if (! Cache::has($object, $hash)) {
    $result = call_user_func($callback, $backtrace->getArguments());

    Cache::set($object, $hash, $result);
}

return Cache::get($object, $hash);

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email freek@spatie.be instead of using the issue tracker.

Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Samberstraat 69D, 2060 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

Credit for the idea of the once function goes to Taylor Otwell. The code for this package is based upon the code he was kind enough to share with us.

Support us

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Does your business depend on our contributions? Reach out and support us on Patreon.
All pledges will be dedicated to allocating workforce on maintenance and new awesome stuff.

License

The MIT License (MIT). Please see License File for more information.

主要指标

概览
名称与所有者spatie/once
主编程语言PHP
编程语言PHP (语言数: 1)
平台
许可证MIT License
所有者活动
创建于2016-11-06 21:34:54
推送于2025-06-16 06:19:14
最后一次提交
发布数18
最新版本名称3.1.1 (发布于 )
第一版名称0.0.1 (发布于 )
用户参与
星数1.4k
关注者数10
派生数58
提交数196
已启用问题?
问题数0
打开的问题数0
拉请求数54
打开的拉请求数1
关闭的拉请求数18
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?