stellarwp / memoize
A flexible memoization library for memory caching.
Installs: 1 179
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 4
Forks: 0
Open Issues: 0
Requires
- stellarwp/arrays: ^1.2
Requires (Dev)
This package is auto-updated.
Last update: 2025-01-07 03:27:57 UTC
README
A flexible memoization library for memory caching.
Table of Contents
Memoization
Memoization is the process of caching the results of expensive function calls so that they can be reused when the same inputs occur again.
Installation
It's recommended that you install Memoize as a project dependency via Composer:
composer require stellarwp/memoize
We actually recommend that this library gets included in your project using Strauss.
Luckily, adding Strauss to your
composer.json
is only slightly more complicated than adding a typical dependency, so checkout our strauss docs.
Notes on examples
All namespaces within the examples will be using the StellarWP\Memoize
, however, if you are using Strauss, you will need to prefix these namespaces with your project's namespace.
Usage
Simple example
use StellarWP\Memoize\Memoizer; $memoizer = new Memoizer(); $memoizer->set('foo', 'bar'); if ($memoizer->has('foo')) { echo $memoizer->get('foo'); // Outputs: bar } // Unsets foo from the memoization cache. $memoizer->forget('foo');
Setting a nested structure
Memoize allows you to use dot notation to set, get, and forget values from a nested structure. This allows you to easily add/fetch values and then purge individual items or whole collections of items.
use StellarWP\Memoize\Memoizer; $memoizer = new Memoizer(); $memoizer->set('foo.bar.bork', 'baz'); // This results in the following cache: // [ // 'foo' => [ // 'bar' => [ // 'bork' => 'baz', // ], // ], // ] // You can fetch the value like so: $value = $memoizer->get('foo.bar.bork'); echo $value; // Outputs: baz // You can fetch anywhere up the chain: $value = $memoizer->get('foo.bar'); echo $value; // Outputs: [ 'bork' => 'baz' ] $value = $memoizer->get('foo'); echo $value; // Outputs: [ 'bar' => [ 'bork' => 'baz' ] ] $value = $memoizer->get(); echo $value; // Outputs: [ 'foo' => [ 'bar' => [ 'bork' => 'baz' ] ] ]
Purging a nested structure
use StellarWP\Memoize\Memoizer; $memoizer = new Memoizer(); $memoizer->set('foo.bar.bork', 'baz'); $memoizer->forget('foo.bar.bork'); // This results in the following cache: // [ // 'foo' => [ // 'bar' => [], // ], // ] $memoizer->forget('foo.bar'); // This results in the following cache: // [ // 'foo' => [], // ] $memoizer->forget('foo'); // This results in the following cache: // [] $memoizer->forget(); // This results in the following cache: // []
Caching with closures
Memoize also supports using closures as values that get resolved before setting in the cache.
use StellarWP\Memoize\Memoizer; $memoizer = new Memoizer(); $memoizer->set('foo', static function () { return 'bar'; }); echo $memoizer->get('foo'); // Outputs: bar
Using with a dependency injection container
Project class
<?php declare(strict_types=1); namespace StellarWP\MyProject; use StellarWP\Memoize\MemoizerInterface; // Dependencies automatically auto-wired due to the definitions in ServiceProvider.php via // $this->container->get( MyProjectClass::class ) /** * An example class inside your project using the Memoize library. */ class MyProjectClass { private MemoizerInterface $memoizer; public function __construct( MemoizerInterface $memoizer ) { $this->memoizer = $memoizer; } public function get( string $name ): string { $result = $this->memoizer->get( $name ); if ( ! $result ) { $result = 'some very expensive operation'; $this->memoizer->set( $name, $result ); } return $result; } public function delete( string $name ): bool { $this->memoizer->forget( $name ); // Run delete operation... return true; } }
Service Provider
<?php declare(strict_types=1); namespace StellarWP\Memoize; use StellarWP\ContainerContract\ContainerInterface; use StellarWP\Memoize\Contracts\DriverInterface; use StellarWP\Memoize\Contracts\MemoizerInterface; use StellarWP\Memoize\Drivers\MemoryDriver; /** * Container ServiceProvider to tell the DI Container how to build everything when another * instance is requested from the Container that uses our interface. * * @example $this->container->get( MyProjectClass::class ); */ final class ServiceProvider { private ContainerInterface $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function register(): void { $this->container->singleton( DriverInterface::class, MemoryDriver::class ); $this->container->bind( MemoizerInterface::class, Memoizer::class ); } }
Drivers
Memoize comes with a single driver out of the box, but you can also create your own using the StellarWP\Memoize\Contracts\DriverInterface
.
MemoryDriver
The MemoryDriver
is a simple in-memory driver. Basically, contains an array property in the driver that holds the memoized values. You can manually specify the use of this driver or any other driver like so:
use StellarWP\Memoize\Memoizer; use StellarWP\Memoize\Drivers\MemoryDriver; $memoizer = new Memoizer(new MemoryDriver());
Traits
The MemoizeTrait
provides a convenient way to add memoization to your classes, ensuring that cached results are isolated to each instance,
preventing cross-talk or key collisions between different objects. Ideal for enhancing existing classes with lightweight, instance-specific caching.
💡 The MemoizeTrait uses in-memory storage only and cannot be changed.
<?php declare(strict_types=1); namespace StellarWP\MyProject; use StellarWP\Memoize\MemoizerInterface; use StellarWP\Memoize\Traits\MemoizeTrait; /** * An example class inside your project. */ class MyProjectClass implements MemoizerInterface { use MemoizeTrait; public function find( string $id ): string { $result = $this->get( $id ); if ( ! $result ) { $result = 'some very expensive operation'; $this->set( $id, $result ); } return $result; } public function delete( string $id ): bool { $this->forget( $id ); // Run delete operation... return true; } }