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

In Memory Cache Laravel Package

beste/in-memory-cache

Lightweight PSR-6 in-memory cache for PHP. Ideal as a default cache implementation and for fast, dependency-free tests. Supports expirations and can use a PSR-20 clock (e.g. frozen clock) for deterministic time-based behavior.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require beste/in-memory-cache
    
  2. Basic Usage:

    use Beste\Cache\InMemoryCache;
    
    $cache = new InMemoryCache();
    $item = $cache->getItem('test_key');
    $item->set('test_value');
    $cache->save($item);
    
    // Retrieve later
    $retrievedItem = $cache->getItem('test_key');
    $value = $retrievedItem->get(); // 'test_value'
    
  3. Laravel Integration: Register the cache driver in config/cache.php:

    'drivers' => [
        'in_memory' => [
            'driver' => 'cache',
            'store' => Beste\Cache\InMemoryCache::class,
        ],
    ],
    

    Then set the driver in .env:

    CACHE_DRIVER=in_memory
    
  4. First Use Case: Replace Redis/Memcached in local development or tests to avoid external dependencies:

    // In a test file
    public function test_cache_functionality()
    {
        $cache = new Beste\Cache\InMemoryCache();
        $cache->set('test', 'value', now()->addMinutes(10));
        $this->assertEquals('value', $cache->get('test'));
    }
    

Implementation Patterns

Usage Patterns

  1. Testing Workflows:

    • Use in-memory cache as a test double for PSR-6 interfaces:
      $cache = new Beste\Cache\InMemoryCache();
      $cache->set('user_data', $user, 300); // 5 minutes TTL
      $this->assertEquals($user, $cache->get('user_data'));
      
    • Frozen Time Testing: Integrate with beste/clock for deterministic expiry tests:
      use Beste\Clock\FrozenClock;
      
      $clock = FrozenClock::fromUTC();
      $cache = new Beste\Cache\InMemoryCache($clock);
      
      $cache->set('time_test', 'value', now()->addMinutes(5));
      $clock->setTo($clock->now()->addMinutes(6));
      $this->assertNull($cache->get('time_test')); // Expired
      
  2. Laravel-Specific Patterns:

    • Cache Tags: Leverage Laravel’s Cache::tags() with in-memory cache (though tags are not natively supported by PSR-6, you can implement a wrapper):
      class TaggedInMemoryCache extends Beste\Cache\InMemoryCache
      {
          public function tags(array $tags): void
          {
              // Custom logic to handle tags
          }
      }
      
    • Cache Events: Listen to Cache::store() events (e.g., Cache::store('in_memory')->flush()) to clear the cache programmatically.
  3. Fallback Strategy:

    • Use as a secondary cache in Laravel’s Cache facade:
      Cache::store('in_memory')->remember('fallback_key', 60, function () {
          return App::make('expensive_service')->fetchData();
      });
      
  4. Memory Management:

    • Manual Cleanup: Clear the cache after tests or long-running processes:
      $cache->clear(); // PSR-6 method
      
    • TTL-Based Eviction: Rely on expiresAfter() or expiresAt() to auto-cleanup:
      $item = $cache->getItem('temp_data');
      $item->set('data')->expiresAfter(new DateInterval('PT1H'));
      $cache->save($item);
      

Integration Tips

  1. PSR-6 Adapter:

    • Wrap the cache in Laravel’s Cache facade using a PSR-6 adapter (e.g., spatie/laravel-cache):
      Cache::extend('in_memory', function ($app) {
          return new CacheManager([
              'store' => Beste\Cache\InMemoryCache::class,
          ]);
      });
      
  2. Clock Integration:

    • For time-sensitive tests, inject a Beste\Clock\FrozenClock to control expiry:
      $clock = FrozenClock::fromUTC();
      $cache = new Beste\Cache\InMemoryCache($clock);
      
  3. Hybrid Caching:

    • Combine with Redis for production while using in-memory for tests:
      // config/cache.php
      'default' => env('CACHE_DRIVER', 'redis'),
      'stores' => [
          'in_memory' => [
              'driver' => 'cache',
              'store' => Beste\Cache\InMemoryCache::class,
          ],
          'redis' => [
              'driver' => 'redis',
              // Redis config...
          ],
      ],
      
  4. Serialization Handling:

    • For complex objects, use Laravel’s serialize() helper:
      $data = ['user' => User::find(1)];
      $cache->set('complex_data', serialize($data), 300);
      $cachedData = unserialize($cache->get('complex_data'));
      

Gotchas and Tips

Pitfalls

  1. No Persistence:

    • Issue: Cache is wiped on process restart (e.g., Laravel queue workers, CLI scripts).
    • Fix: Use only for short-lived data or implement periodic Cache::clear() in long-running processes.
  2. Thread Safety:

    • Issue: Not thread-safe. Concurrent writes in multi-process environments (e.g., Laravel Horizon) can corrupt data.
    • Fix: Restrict to single-process use (e.g., HTTP requests) or use a mutex (e.g., Swoole\Atomic).
  3. Memory Bloat:

    • Issue: Unbounded growth if not using TTL or manual cleanup.
    • Fix: Enforce TTLs or clear cache after use:
      $cache->clear(); // After tests or batch operations
      
  4. Key Validation:

    • Issue: PSR-6 requires keys to be UTF-8 and ≤64 chars (though this package is more lenient).
    • Fix: Sanitize keys before use:
      $key = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', $rawKey);
      
  5. Serialization Limits:

    • Issue: Complex objects (e.g., closures, resources) may fail to serialize.
    • Fix: Use serialize() for custom objects or avoid caching them.
  6. Laravel Cache Facade Quirks:

    • Issue: Some Laravel cache methods (e.g., Cache::tags()) are not PSR-6-compliant.
    • Fix: Use raw PSR-6 methods or extend the class:
      $cache->getItem('key')->set('value')->expiresAfter(60);
      $cache->save($cache->getItem('key'));
      

Debugging

  1. Inspect Cache Contents:

    • Dump the internal storage (not exposed by default, but you can extend the class):
      class DebugInMemoryCache extends Beste\Cache\InMemoryCache
      {
          public function debugDump(): array
          {
              return $this->storage->getAll();
          }
      }
      
  2. TTL Issues:

    • Symptom: Items expire unexpectedly.
    • Debug: Verify the clock is correct (especially in tests):
      $clock = $cache->getClock();
      $this->assertInstanceOf(ClockInterface::class, $clock);
      
  3. Performance Bottlenecks:

    • Symptom: Slow cache operations in tests.
    • Fix: Avoid deep object serialization or use simpler data structures.

Tips

  1. Test Isolation:

    • Clear the cache between tests to avoid pollution:
      public function tearDown(): void
      {
          $this->cache->clear();
      }
      
  2. Laravel Service Provider:

    • Register the cache as a singleton for reuse:
      public function register()
      {
          $this->app->singleton(Beste\Cache\InMemoryCache::class, function () {
              return new Beste\Cache\InMemoryCache();
          });
      }
      
  3. Clock Customization:

    • Use Beste\Clock\SystemClock for production-like behavior in tests:
      $cache = new Beste\Cache\InMemoryCache(new SystemClock());
      
  4. Key Naming:

    • Prefix keys to avoid collisions (e.g., test_, dev_):
      $cache->set('test_user_data', $user, 300);
      
  5. Laravel Cache Events:

    • Listen to cache events to log or clear the in-memory store:
      Cache::store('in_memory')->flush();
      
  6. Benchmarking:

    • Compare performance with Redis in tests:
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope