diff --git a/README.md b/README.md index 88c7bd7..58374cf 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ This package provides you with a simple PHP trait, which adds [memoization](https://en.wikipedia.org/wiki/Memoization) to your classes! It's inspired by spaties once package, but it is up to **100% faster**! +Note: As this is a trait it only runs in class contexts and not statically. + ## Installation ``` bash @@ -44,21 +46,20 @@ The `memoize` method will only run **once per combination** of `use` variables t For lower php versions, it will run **once per combination** of argument values the ***containing method*** receives. ```php -class MyClass +$myClass = new class() { - /** - * It also works in static context! - */ - public static function getNumberForLetter($letter) + use HasMemoization; + + public function getNumberForLetter($letter) { - return self::memoize(function () use ($letter) { + return $this->memoize(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. +So calling `$myClass->getNumberForLetter('A')` will always return the same result, but calling `$myClass->getNumberForLetter('B')` will return something else. As described above, spaties once package uses the arguments of the ***containing method*** for the **once per combination** idea. We think this feels a bit unintuitive and in certain circumstances will affect performance. So we use the `use` variables of the closure as the **once per combination** key. As a fallback for php8.0 and lower or if you like/need to, we also let you fully self define your **once per combination** key in a second optional parameter of the closure. diff --git a/src/HasMemoization.php b/src/HasMemoization.php index fc1b120..9d830a8 100644 --- a/src/HasMemoization.php +++ b/src/HasMemoization.php @@ -9,41 +9,41 @@ trait HasMemoization * * @var array */ - protected static $memoizationCache = []; + protected $memoizationCache = []; /** * specifies if memoization should be applied * * @var bool */ - protected static $memoizationEnabled = true; + protected $memoizationEnabled = true; /** * @return void */ - public static function enableMemoization() + public function enableMemoization() { - self::$memoizationEnabled = true; + $this->memoizationEnabled = true; } /** * @return void */ - public static function disableMemoization() + public function disableMemoization() { - self::$memoizationEnabled = false; + $this->memoizationEnabled = false; } /** * @return bool */ - public static function isEnabledMemoization(): bool + public function isEnabledMemoization(): bool { if (isset($_ENV['MEMOIZATION_GLOBALLY_DISABLED'])) { return $_ENV['MEMOIZATION_GLOBALLY_DISABLED']; } - return self::$memoizationEnabled; + return $this->memoizationEnabled; } /** @@ -52,9 +52,9 @@ public static function isEnabledMemoization(): bool * @return array|mixed * @throws \ReflectionException */ - public static function memoize(callable $callback, array $customCombiArgs = []) + public function memoize(callable $callback, array $customCombiArgs = []) { - if (!self::isEnabledMemoization()) { + if (!$this->isEnabledMemoization()) { return $callback(); } @@ -75,16 +75,16 @@ public static function memoize(callable $callback, array $customCombiArgs = []) $combiArgs = $customCombiArgs; } - $hash = self::getMemoCacheHash($combiArgs, $prefix); + $hash = $this->getMemoCacheHash($combiArgs, $prefix); - if (!array_key_exists($hash, self::$memoizationCache)) { - self::$memoizationCache[$hash] = $callback(); + if (!array_key_exists($hash, $this->memoizationCache)) { + $this->memoizationCache[$hash] = $callback(); } - return self::$memoizationCache[$hash]; + return $this->memoizationCache[$hash]; } - private static function getMemoCacheHash(array $arguments, string $prefix): string + private function getMemoCacheHash(array $arguments, string $prefix): string { $normalizedArguments = array_map(function ($argument) { return is_object($argument) ? spl_object_hash($argument) : $argument; diff --git a/tests/MemoTest.php b/tests/MemoTest.php index d6982fd..05d0092 100644 --- a/tests/MemoTest.php +++ b/tests/MemoTest.php @@ -102,29 +102,6 @@ public function getNull() expect($testClass->getRandomNumber())->toBe($firstNumber); }); -it('will run callback once on static method', function () { - $object = new class() { - use HasMemoization; - - public static function getNumber() - { - return self::memoize(function () { - return rand(1, 10000000); - }); - } - }; - $class = get_class($object); - - $firstResult = $class::getNumber(); - - expect($firstResult)->toBeGreaterThanOrEqual(1); - expect($firstResult)->toBeLessThanOrEqual(10000000); - - foreach (range(1, 100) as $i) { - expect($class::getNumber())->toBe($firstResult); - } -}); - it('can enable and disable the cache', function () { $testClass = new class() { use HasMemoization; @@ -137,15 +114,15 @@ public function getNumber() } }; - expect($testClass::isEnabledMemoization())->toBeTrue(); + expect($testClass->isEnabledMemoization())->toBeTrue(); expect($testClass->getNumber())->toBe($testClass->getNumber()); - $testClass::disableMemoization(); + $testClass->disableMemoization(); expect($testClass->isEnabledMemoization())->toBeFalse(); expect($testClass->getNumber())->not()->toBe($testClass->getNumber()); - $testClass::enableMemoization(); - expect($testClass::isEnabledMemoization())->toBeTrue(); + $testClass->enableMemoization(); + expect($testClass->isEnabledMemoization())->toBeTrue(); expect($testClass->getNumber())->toBe($testClass->getNumber()); }); // @@ -223,21 +200,4 @@ public function getNumber() // dump($diff1, $diff2); expect($diff1)->toBeLessThan($diff2); -}); - -it('will run statically without class context', function () { - function getNumber() { - return MemoHelper::memoize(function () { - return rand(1, 10000000); - }); - } - - $firstResult = getNumber(); - - expect($firstResult)->toBeGreaterThanOrEqual(1); - expect($firstResult)->toBeLessThanOrEqual(10000000); - - foreach (range(1, 100) as $i) { - expect(getNumber())->toBe($firstResult); - } }); \ No newline at end of file