Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laminas Cache Storage Adapter Filesystem Laravel Package

laminas/laminas-cache-storage-adapter-filesystem

Filesystem storage adapter for laminas-cache. Provides a cache backend that persists items on disk with configurable options and integration with Laminas Cache storage interfaces, suitable for local or shared filesystem caching.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

To start using laminas/laminas-cache-storage-adapter-filesystem in Laravel, install it via Composer:

composer require laminas/laminas-cache-storage-adapter-filesystem

First Use Case: Basic Cache Storage

Leverage the adapter for simple file-based caching in Laravel:

use Laminas\Cache\Storage\Adapter\Filesystem;
use Laminas\Cache\Storage\Factory;

// Create a filesystem adapter
$cacheDir = storage_path('framework/cache');
$adapter = new Filesystem([
    'cache_dir' => $cacheDir,
]);

// Store data
$adapter->setItem('key', 'value', 3600); // 1-hour TTL

// Retrieve data
$value = $adapter->getItem('key')->get();

Laravel Integration (Service Provider)

Register the adapter in AppServiceProvider:

use Laminas\Cache\Storage\Adapter\Filesystem;
use Illuminate\Support\ServiceProvider;

public function register()
{
    $this->app->singleton('laminas.cache.filesystem', function ($app) {
        return new Filesystem([
            'cache_dir' => $app->storagePath('framework/cache'),
        ]);
    });
}

First Use Case: PSR-6/PSR-16 Compliance

For PSR-6/PSR-16 compatibility (Laravel 8+):

use Laminas\Cache\Storage\Adapter\Filesystem;
use Laminas\Cache\Storage\Plugin\Serializer;
use Laminas\Cache\Storage\Plugin\Clock;

$adapter = new Filesystem([
    'cache_dir' => storage_path('framework/cache'),
    'plugins' => [
        new Serializer(),
        new Clock(),
    ],
]);

// PSR-6/PSR-16 methods
$adapter->set('key', 'value', 3600);
$value = $adapter->get('key');

Implementation Patterns

Workflow: Caching Expensive Operations

public function getExpensiveData()
{
    $cacheKey = 'expensive_data_' . md5($request->input('query'));
    $adapter = app('laminas.cache.filesystem');

    if ($adapter->hasItem($cacheKey)) {
        return $adapter->getItem($cacheKey)->get();
    }

    $data = $this->fetchExpensiveData(); // Database query, API call, etc.
    $adapter->setItem($cacheKey, $data, 3600); // Cache for 1 hour
    return $data;
}

Workflow: Cache Invalidation

public function invalidateCache()
{
    $adapter = app('laminas.cache.filesystem');
    $adapter->removeItem('expensive_data_' . md5($request->input('query')));
    // Or clear all items
    $adapter->clear();
}

Integration with Laravel's Cache Facade

Extend Laravel's cache facade to support Laminas adapter:

// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Cache;

public function boot()
{
    Cache::extend('laminas', function ($app) {
        return Cache::repository(new LaminasCacheStore($app['laminas.cache.filesystem']));
    });
}

// app/Providers/LaminasCacheStore.php
use Illuminate\Contracts\Cache\Store;

class LaminasCacheStore implements Store
{
    protected $laminasAdapter;

    public function __construct($adapter)
    {
        $this->laminasAdapter = $adapter;
    }

    public function get($key)
    {
        return $this->laminasAdapter->getItem($key)->get();
    }

    public function put($key, $value, $seconds = null)
    {
        $this->laminasAdapter->setItem($key, $value, $seconds);
    }

    // Implement other Cache methods...
}

Pattern: Cache Tags for Batch Invalidation

$adapter = app('laminas.cache.filesystem');
$adapter->setItem('user:123:posts', $posts, 3600, ['user:123']);

// Later, invalidate all items tagged 'user:123'
$adapter->getMetadataPool()->getItemTags('user:123')->each(function ($tag) {
    $adapter->removeItem($tag);
});

Pattern: Serialization Handling

For unserializable objects, configure the adapter:

$adapter = new Filesystem([
    'cache_dir' => storage_path('framework/cache'),
    'unserializable_classes' => [
        'App\Models\User',
        'App\Services\ComplexService',
    ],
]);

Gotchas and Tips

Pitfalls

  1. File Permissions: Ensure the cache directory (storage/framework/cache) is writable by the web server user.

    chmod -R 775 storage/framework/cache
    
  2. Key Collisions: Avoid keys with special characters (except .). Use md5() or hash() for dynamic keys:

    $safeKey = 'prefix_' . md5('user:123:posts');
    
  3. TTL Calculation: TTL is calculated on-write, not on-read. Ensure your TTL values account for clock skew in distributed environments.

  4. File Suffix Change: Since v3.0, the adapter uses .cache suffix instead of .dat. Existing .dat files will not be compatible.

  5. Unserializable Objects: If storing complex objects, either:

    • Use a Serializer plugin, or
    • Configure unserializable_classes in the adapter options.

Debugging Tips

  1. Check Cache Files: Inspect storage/framework/cache for corrupted or unexpected files. Files are named as:

    {hash}.cache
    

    where {hash} is a hash of the cache key.

  2. Metadata Inspection: Use getMetadata() to debug cache items:

    $metadata = $adapter->getMetadata('key');
    dd($metadata->getExpirationTime(), $metadata->getCreationTime());
    
  3. Clock Skew: If TTLs seem off, verify your system clock or use a Clock plugin:

    use Laminas\Cache\Storage\Plugin\Clock;
    
    $adapter = new Filesystem([
        'cache_dir' => storage_path('framework/cache'),
        'plugins' => [new Clock()],
    ]);
    

Configuration Quirks

  1. Cache Directory: Defaults to sys_get_temp_dir(). Override explicitly:

    $adapter = new Filesystem(['cache_dir' => storage_path('framework/cache')]);
    
  2. Umask: The adapter uses 0600 by default. Change via FilesystemInteraction if needed (requires custom implementation).

  3. Tag Support: Tags are stored in separate files with a .tags suffix. Ensure your cache directory has enough space for tags.

Extension Points

  1. Custom Serialization: Attach a Serializer plugin for custom serialization:

    use Laminas\Cache\Storage\Plugin\Serializer;
    use Laminas\Serializer\SerializerInterface;
    
    $serializer = new YourCustomSerializer();
    $adapter = new Filesystem([
        'cache_dir' => storage_path('framework/cache'),
        'plugins' => [new Serializer($serializer)],
    ]);
    
  2. Custom Clock: Use a Clock plugin for testing or custom time handling:

    use Laminas\Cache\Storage\Plugin\Clock;
    use Laminas\Clock\ClockInterface;
    
    $clock = new YourCustomClock();
    $adapter = new Filesystem([
        'cache_dir' => storage_path('framework/cache'),
        'plugins' => [new Clock($clock)],
    ]);
    
  3. Event Listeners: Extend the adapter by attaching event listeners (requires PSR-14 event dispatching):

    $adapter->getEventDispatcher()->addListener(
        'cache.item.set',
        function ($event) {
            // Log cache writes
            Log::debug('Cache written', ['key' => $event->getKey()]);
        }
    );
    

Performance Tips

  1. Batch Operations: Use getItems() and setItems() for bulk operations to reduce I/O overhead:

    $items = ['key1' => 'value1', 'key2' => 'value2'];
    $adapter->setItems($items, 3600);
    
  2. Memory Usage: For large objects, use getFirstLineOfFile() to peek at metadata without loading the entire file:

    $expiryLine = $adapter->getFirstLineOfFile('key');
    
  3. Directory Structure: Avoid deep directory structures. The adapter hashes filenames to prevent path traversal issues.

Migration Notes

  • From v2.x to v3.x:
    • Update cache files manually if migrating from .dat to .cache.
    • Ensure all cache keys are compatible with PSR-6 (support for . in keys).
    • Update unserializable_classes configuration if using custom serialization.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky