spatie/once
Composer 安装命令:
composer require spatie/once
包简介
A magic memoization function
README 文档
README
A magic memoization function
This package contains a once function. You can pass a callable to it. Here's quick example:
$myClass = new class() { public function getNumber(): int { return once(function () { return rand(1, 10000); }); } };
No matter how many times you run $myClass->getNumber() inside the same request you'll always get the same number.
Are you a visual learner?
Under the hood, this package uses a PHP 8 Weakmap. In this video, you'll see what a weakmap is, together with a nice demo of the package.
Support us
We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.
Installation
You can install the package via composer:
composer require spatie/once
Usage
The once function accepts a callable.
$myClass = new class() { public function getNumber(): int { return once(function () { return rand(1, 10000); }); } };
No matter how many times you run $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::getInstance()->flush();
Disabling the cache
In your tests you probably don't want to cache values. To disable the cache you can call:
Spatie\Once\Cache::getInstance()->disable();
You can re-enable the cache with
Spatie\Once\Cache::getInstance()->enable();
Octane compatibility
Warning
This behaviour is in beta and needs to be tested by the community. You can find this topic in discussion #79.
In order to have once working properly in an Octane environment, Cache::getInstance()->flush() must be called when OperationTerminated event is triggered. You can configure it in config/octane.php file:
// config/octane.php OperationTerminated::class => [ FlushTemporaryContainerInstances::class, // DisconnectFromDatabases::class, // CollectGarbage::class, FlushSpatieOnce::class, // we should create this class we have added here ],
And create the FlushSpatieOnce:class:
// app/Listeners/FlushSpatieOnce.php use Spatie\Once\Cache; class FlushSpatieOnce { public function handle($event) { Cache::getInstance()->flush(); } }
Under the hood
The once function will execute the given callable and save the result in the $values property of Spatie\Once\Cache. This class is a singleton. When we detect that once has already run before, we're just going to return the value stored inside the $values weakmap 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 the weakmap of Spatie\Once\Cache. In the other case, we just return the value from that cache (the $callback isn't executed).
public function has(object $object, string $backtraceHash): bool { if (! isset($this->values[$object])) { return false; } return array_key_exists($backtraceHash, $this->values[$object]); }
Changelog
Please see CHANGELOG for more information what has changed recently.
Testing
composer test
Contributing
Please see CONTRIBUTING for details.
Security
If you've found a bug regarding security please mail security@spatie.be instead of using the issue tracker.
Credits
And a special thanks to Caneco for the logo ✨
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.
License
The MIT License (MIT). Please see License File for more information.
spatie/once 适用场景与选型建议
spatie/once 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 29.82M 次下载、GitHub Stars 达 1.44k, 最近一次更新时间为 2016 年 11 月 06 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「cache」 「callable」 「memoization」 「spatie」 「once」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 spatie/once 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 spatie/once 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 spatie/once 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A library for memoizing repeated function calls.
repository php library
A small helper for memoizing.
A speed layer that enables batch loading, de-duplication, and caching for efficient data fetching over any storage backend.
Memoization for Eloquent (Laravel) Models
Laravel 5 - Repositories to the database layer
统计信息
- 总下载量: 29.82M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1444
- 点击次数: 26
- 依赖项目数: 95
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2016-11-06
