solodkiy / memorize
纯函数的简单缓存
0.1.0
2016-11-21 19:22 UTC
Requires
- php: >=5.4
Requires (Dev)
- humbug/humbug: ~1.0@dev
- phpunit/phpunit: 4.8
This package is auto-updated.
Last update: 2024-08-29 04:25:30 UTC
README
Memorize 是 PHP 的 Python @lazy 装饰器的类似物。
Memorize 为闭包提供简单的参数缓存。它可以用来创建懒加载函数。函数接受闭包和可选的参数 paramsHash。如果之前已经用相同的参数运行了闭包,Memorize 将直接从缓存中返回结果,而无需再次调用闭包。第一次调用时,结果将被计算并存储在缓存中。
缓存存储在全局空间中,用于静态方法和简单函数。对于对象方法中定义的闭包,缓存将存储在这个对象中(两个对象有不同的缓存)。根据设计,缓存仅在脚本运行期间存储。无法设置缓存的有效期或使缓存失效。Memorize 会自动为具有标量参数的闭包计算 paramsHash。如果你的闭包有对象作为参数,你必须计算并传递 paramsHash 作为第二个参数。(参见MemorizeInObjectTest::correctAddDaysToTime测试)
请注意,Memorize 通过文件名、闭包声明的起始行和结束行来计算闭包的哈希值。如果你在一行中声明了两个闭包(例如:在代码混淆之后),Memorize 可能无法正确工作。
安装
composer require solodkiy/memorize
示例
使用 memorize 的单例
之前
class Singleton { /** * @var Singleton */ private static $instance; private function __construct() { // private } public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new Singleton(); } return self::$instance; } }
之后
class Singleton { private function __construct() { // private } public static function getInstance() { return memorize(function() { return new Singleton(); }); } }
懒递归阶乘函数
function factorial($number) { return memorize(function () use ($number) { if ($number <= 0) { throw new \InvalidArgumentException('Number must be natural'); } return ($number == 1) ? 1 : $number * factorial($number - 1); }); }
它也正确地在对象中工作。
之前
class TableGateway { /** * @var array */ private $cacheStatistic = []; public function getA($accountId) { return $this->calculateStatistic($accountId)['a']; } public function getB($accountId) { return $this->calculateStatistic($accountId)['b']; } private function calculateStatistic($accountId) { if (!isset($this->cacheStatistic[$accountId])) { $sql = 'SELECT AVG(price) AS a ...'; $result = $this->db->getRows($sql, [$accountId]); $this->cacheStatistic[$accountId] = $result; } return $this->cacheStatistic[$accountId]; } }
之后
class TableGateway { public function getA($accountId) { return $this->calculateStatistic($accountId)['a']; } public function getB($accountId) { return $this->calculateStatistic($accountId)['b']; } private function calculateStatistic($accountId) { return memorize(function () use ($accountId) { $sql = 'SELECT AVG(price) AS a ...'; return $this->db->getRows($sql, [$accountId]); }); } }