tomloprod/memoize
最新稳定版本:v2.3.0
Composer 安装命令:
composer require tomloprod/memoize
包简介
Memoize is a lightweight PHP library designed to handle memoization with ease.
关键字:
README 文档
README
🧠 Memoize - PHP Memoization Library
High-performance memoization and function caching library for PHP
🎯 About Memoize
Memoize is a lightweight PHP library designed to implement memoization and function caching techniques with ease.
Transform expensive function calls into lightning-fast cache lookups with zero configuration.
✨ Features
|
🔑 Key-based Memoization ⚡ Single Execution 🏷️ Namespaces |
🧠 LRU Cache 📊 Cache Analytics 🏃 Runtime Flags 🔄 Enable/Disable |
🚀 Quick Start - PHP Memoization
Installation
composer require tomloprod/memoize
Basic Usage
🏷️ Namespace Organization
If you want to get the most out of the package and better organize your memoization, we recommend using namespaces.
When using namespaces, if you use a $key with a null value, the callback won’t be executed (especially useful in certain cases).
// Organize cache by context $userSettings = memoize() ->for(UserSettings::class) ->memo($userId, fn() => UserSettings::where('user_id', $userId)->first()); $productCache = memoize() ->for(Product::class) ->memo($productId, fn() => Product::with('variants')->find($productId));
🔑 Key-based Memoization
You can also not use namespaces and just memoize keys.
// Expensive API call cached by key $weather = memoize()->memo( 'weather_london', fn() => Http::get('api.weather.com/london')->json() ); // Database query with dynamic key $user = memoize()->memo( "user_{$id}", fn() => User::with('profile', 'orders')->find($id) );
⚡ Single Execution Functions
// Initialize expensive resources only once $services = memoize()->once(fn() => [ 'redis' => new Redis(), 'elasticsearch' => new Client(), 'logger' => new Logger(), ]); $redis = $services()['redis']; // Initialized once $same = $services()['redis']; // Same instance
🧠 Memory Management
The library uses an LRU (Least Recently Used) algorithm to automatically manage memory and prevent unlimited cache growth.
How does LRU work?
- Maintains a record of the access order for cache entries
- When the maximum limit (
maxSize) is reached, automatically removes the least recently used entry - Every time you access an entry (read or write), it moves to the front of the queue
- Older entries remain at the end and are candidates for removal
This ensures that the most relevant and frequently used data remains in memory, while obsolete data is automatically removed.
// Set LRU cache limit (by default, there is no max size) memoize()->setMaxSize(1000); // Cache statistics $stats = memoize()->getStats(); // ['size' => 150, 'maxSize' => 1000, 'head' => [...], 'tail' => [...]] // Clear specific or all cache memoize()->forget('user_123'); memoize()->for('App\\Model\\User')->forget('123'); // Or clear all cache memoize()->flush();
🔄 Enable/Disable Memoization
You can temporarily disable memoization to bypass caching when needed. When disabled, callbacks are executed every time without storing results in cache.
// Disable memoization memoize()->disable(); // Now all memo() calls will execute callbacks without caching $result1 = memoize()->memo('key', fn() => expensiveOperation()); // Executes $result2 = memoize()->memo('key', fn() => expensiveOperation()); // Executes again // Re-enable memoization memoize()->enable(); // Now caching works normally again $result3 = memoize()->memo('key', fn() => expensiveOperation()); // Executes and caches $result4 = memoize()->memo('key', fn() => expensiveOperation()); // Returns cached value // Check current state if (memoize()->isEnabled()) { // Memoization is active }
Use cases:
- Debugging: Temporarily disable caching to see fresh data
- Testing: Ensure callbacks execute every time during tests
- Conditional behavior: Disable caching based on environment or conditions
🏃 Runtime Flags
Control memoization behavior dynamically during execution with runtime flags. These flags exist only in memory and reset between requests/processes.
How do runtime flags work?
- Flags are stored in memory during the current execution
- They allow conditional behavior without external configuration
- Perfect for debug modes, logging control, and dynamic optimizations
- Automatically cleared when the process ends
// Skip cache during testing memoize()->enableFlag('bypass_cache'); $userData = memoize()->memo("user_{$id}", function() use ($id) { if (memoize()->hasFlag('bypass_cache')) { return User::fresh()->find($id); // Always fetch from DB in tests } return User::find($id); }); // Feature toggles without external dependencies memoize()->enableFlag('new_algorithm'); $result = memoize()->memo($cacheKey, function() { if (memoize()->hasFlag('new_algorithm')) { return $this->calculateWithNewAlgorithm(); } return $this->calculateWithOldAlgorithm(); }); // Development vs Production behavior if (app()->environment('local') && memoize()->hasFlag('dev_mode')) { memoize()->enableFlags(['verbose_logging', 'bypass_cache']); } // Model boot method with conditional service calls class Product extends Model { protected static function boot() { parent::boot(); static::updated(function ($product) { // Only call external stock service if flag is not set if (! memoize()->hasFlag('disableStockService')) { app(StockService::class)->updateInventory($product); } }); } }
Runtime Flag Methods:
| Method | Description |
|
enableFlag(string $flag) | Enable a specific runtime flag |
|
disableFlag(string $flag) | Disable a specific runtime flag |
|
toggleFlag(string $flag) | Toggle flag state (enabled/disabled) |
|
hasFlag(string $flag): bool | Check if a specific flag is enabled |
|
enableFlags(array $flags) | Enable multiple flags at once |
|
disableFlags(array $flags) | Disable multiple flags at once |
|
hasAnyFlag(array $flags): bool | Check if at least one flag is enabled |
|
hasAllFlags(array $flags): bool | Check if all specified flags are enabled |
|
getFlags(): array | Get all currently enabled flags |
|
clearFlags() | Clear all enabled flags |
💡 Advanced Examples
🏃♂️ Performance Optimization
// Fibonacci with memoization - O(n) instead of O(2^n) function fibonacci(int $n): int { return memoize()->memo( "fib_{$n}", fn() => $n <= 1 ? $n : fibonacci($n - 1) + fibonacci($n - 2) ); } // Complex data aggregation $salesReport = memoize()->memo( "sales_report_{$month}", fn() => Order::whereMonth('created_at', $month) ->with('items.product') ->get() ->groupBy('status') ->map(fn($orders) => $orders->sum('total')) );
📖 API Reference
Core Methods
| Method | Description |
|
memo(string|int|float|null $key, callable $callback) |
Key-based memoization - Execute callback and cache result by key. Returns cached value on subsequent calls. |
|
once(callable $callback) |
Single execution - Returns a wrapper function that executes the callback only once, caching the result forever. |
|
for(string $class) |
Namespace organization - Set namespace to organize cache by class/context. Automatically cleared after use. |
Cache Management
| Method | Description |
|
has(string|int|float $key): bool | Check if a key exists in cache |
|
forget(string|int|float $key): bool | Remove specific key from cache |
|
flush(): void | Clear all cached values |
|
setMaxSize(?int $maxSize): void | Set maximum entries (LRU eviction) |
|
getStats(): array | Get detailed cache statistics |
|
disable(): void | Disable memoization (callbacks execute without caching) |
|
enable(): void | Enable memoization (default state) |
|
isEnabled(): bool | Check if memoization is currently enabled |
⚙️ Requirements & Installation
- PHP 8.2+
- Composer
composer require tomloprod/memoize
🧑🤝🧑 Contributing
Contributions are welcome, and are accepted via pull requests. Please review these guidelines before submitting any pull requests.
Memoize was created by Tomás López and open-sourced under the MIT license.
统计信息
- 总下载量: 1.71k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 41
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-07-25