nette/caching
High-performance caching library from Nette. Provides flexible cache storage backends, automatic expiration, dependency-based invalidation, and easy integration for PHP apps. Ideal for speeding up responses and reducing database or API load.
## Getting Started
### Minimal Setup
1. **Installation**
Add the package via Composer:
```bash
composer require nette/caching
For Laravel integration (if using a wrapper), ensure compatibility with your Laravel version (v3.x+).
Basic Cache Initialization
Define a storage backend (e.g., FileStorage for local caching):
use Nette\Caching\Storages\FileStorage;
$storage = new FileStorage($cacheDir, $cacheNamespace);
First Use Case: Simple Key-Value Cache
$cache = new \Nette\Caching\Cache($storage, $cacheNamespace);
// Save data with expiration (e.g., 3600 seconds = 1 hour)
$cache->save('user_data', $userData, [
\Nette\Caching\Cache::EXPIRES_AT => time() + 3600,
]);
// Retrieve data
$data = $cache->load('user_data');
Leverage Laravel’s Service Container (if using a wrapper)
Register the cache in config/services.php or a provider:
$this->app->singleton('cache.nette', function ($app) {
$storage = new FileStorage(storage_path('framework/cache'), 'laravel_nette');
return new \Nette\Caching\Cache($storage, 'laravel_nette');
});
Multi-Backend Caching
Use different storage backends (e.g., RedisStorage, MemcachedStorage, FileStorage) for development/production:
// Switch between backends based on environment
$storage = config('app.env') === 'production'
? new RedisStorage($redisClient)
: new FileStorage(storage_path('cache'), 'dev_cache');
$cache = new \Nette\Caching\Cache($storage, 'app_cache');
Dependency-Based Caching (Macros) Cache dynamic content (e.g., API responses) with file dependencies:
$cache->startCapture($cacheKey, [
\Nette\Caching\Cache::EXPIRES_AT => time() + 3600,
\Nette\Caching\Cache::DEPENDENCIES => [public_path('config.json')],
]);
echo $cache->captureToString(function () {
return $this->fetchExpensiveData();
});
Bulk Operations Optimize performance with bulk reads/writes (v3.3.0+):
// Bulk load multiple keys
$keys = ['key1', 'key2', 'key3'];
$data = $cache->loadMulti($keys);
// Bulk save (if backend supports it)
$cache->saveMulti([
'key1' => $data1,
'key2' => $data2,
], [
\Nette\Caching\Cache::EXPIRES_AT => time() + 3600,
]);
Namespaced Caching Organize cache keys by namespace (e.g., per-module):
$cache = new \Nette\Caching\Cache($storage, 'module_auth');
$cache->save('user_roles', $roles, [Cache::EXPIRES_AT => time() + 86400]);
Wrapper Class for Laravel Compatibility
Create a facade/class to bridge Nette’s API with Laravel’s Illuminate\Contracts\Cache\Repository:
namespace App\Services;
use Nette\Caching\Cache;
use Illuminate\Contracts\Cache\Store as LaravelStore;
class NetteCache implements LaravelStore {
protected $cache;
public function __construct(Cache $cache) {
$this->cache = $cache;
}
public function get($key, $default = null) {
return $this->cache->load($key, $default);
}
public function put($key, $value, $seconds = null) {
$expiry = $seconds ? time() + $seconds : null;
$this->cache->save($key, $value, [
Cache::EXPIRES_AT => $expiry,
]);
return true;
}
// Implement remaining Laravel methods (eforever, add, forget, etc.)
}
Cache Tags (Partial Support) Simulate Laravel’s tag-based invalidation using Nette’s dependencies:
// Save with a "tag" as a dependency
$cache->save('user_posts', $posts, [
Cache::DEPENDENCIES => ['tags:user_123'],
]);
// Invalidate all keys with the tag (manual approach)
$keys = $cache->getKeys(); // Requires custom implementation
foreach ($keys as $key) {
if (strpos($key, 'tags:user_123') !== false) {
$cache->remove($key);
}
}
Event Listeners (Limited) Use Laravel’s event system to trigger cache invalidation:
// In a service provider
$this->app->booting(function () {
event(new CacheInvalidated('user_123'));
});
// Listen for events
event(new CacheInvalidated($userId));
Configuration
Define cache backends in config/cache.php:
'stores' => [
'nette' => [
'driver' => 'nette',
'storage' => env('CACHE_STORAGE', 'file'),
'path' => storage_path('framework/cache'),
'namespace' => 'laravel_nette',
],
],
No Native Laravel Integration
IStorage interface does not align with Laravel’s Illuminate\Contracts\Cache\Repository.ClassNotFoundException if mixing Nette’s and Laravel’s cache methods.Deprecated Methods
Cache::save() with closures was deprecated in v3.1.0. Use capture() instead:
// Old (deprecated)
$cache->save('key', function () { return $data; });
// New
$cache->startCapture('key', $dependencies);
$result = $cache->captureToString(function () { return $data; });
SQLite Journal Quirks
SQLiteJournal may throw PDOException if the SQLite extension (pdo_sqlite) is missing or misconfigured.pdo_sqlite is enabled in php.ini or use FileJournal as a fallback.storage/logs/ for SQLite-related errors.File Permissions
FileStorage requires writable directories. Laravel’s storage/framework/cache may need permissions:
chmod -R 775 storage/framework/cache
PermissionDeniedException in logs.Namespace Collisions
NAMESPACE_SEPARATOR (internal) may conflict with custom keys if not handled properly.:: in cache keys or wrap them:
$safeKey = str_replace('::', '__', $originalKey);
Bulk Operations Limitations
saveMulti). FileStorage and RedisStorage do, but MemcachedStorage may not.MethodNotSupportedException and fall back to individual saves.PHP Version Mismatches
composer.json requirements:
"require": {
"php": ">=8.1",
"nette/caching": "^3.4"
}
Enable Debug Logging Configure Nette’s logger to output cache operations:
$storage = new FileStorage($cacheDir, $namespace, [
'logger' => new \Nette\Utils\Logger($logger),
]);
Inspect Cache Contents Dump cache keys and metadata:
$keys = $cache->getKeys(); // Requires custom implementation for most backends
foreach ($keys as $key) {
$metadata = $cache->getMetadata($key);
\Log::debug("
How can I help you explore Laravel packages today?