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

Polyfill Apcu Laravel Package

symfony/polyfill-apcu

Symfony Polyfill for APCu: provides apcu_* functions and the APCuIterator class for projects relying on the legacy APC extension, enabling compatible caching APIs when APCu isn’t available or APC is used.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/polyfill-apcu
    

    Add to composer.json under require:

    "symfony/polyfill-apcu": "^1.35"
    
  2. First Use Case: Enable the polyfill in your AppServiceProvider:

    use Symfony\Polyfill\Apcu\ApcuFunctions;
    
    public function boot()
    {
        if (!extension_loaded('apcu')) {
            ApcuFunctions::register();
            \Log::info('APCu polyfill activated (non-native environment)');
        }
    }
    
  3. Verify Functionality: Test with Laravel’s cache facade:

    Cache::put('test_key', 'test_value', 60);
    $value = Cache::get('test_key');
    

Where to Look First

  • Laravel Cache Configuration: Check config/cache.php for apcu driver usage.
  • Session Configuration: Verify config/session.php for apcu driver.
  • Existing apcu_* Calls: Audit your codebase for direct apcu_* function usage.

Implementation Patterns

Usage Patterns

  1. Environment-Aware Activation: Use .env to control polyfill activation:

    APCU_POLYFILL=true
    

    Then in AppServiceProvider:

    if (env('APCU_POLYFILL', false) && !extension_loaded('apcu')) {
        ApcuFunctions::register();
    }
    
  2. Laravel Cache Store Integration: Extend the ApcuStore to log polyfill usage:

    Cache::extend('apcu', function ($app) {
        return new class($app['cache.store.apcu'], $app) extends \Illuminate\Cache\ApcuStore {
            public function store($key, $value, $ttl = null)
            {
                if (ApcuFunctions::isRegistered()) {
                    \Log::debug("APCu polyfill storing: {$key}");
                }
                return parent::store($key, $value, $ttl);
            }
        };
    });
    
  3. Fallback Mechanism: Implement a fallback cache driver if polyfill fails:

    Cache::extend('apcu_fallback', function ($app) {
        return new class($app) extends \Illuminate\Cache\Repository {
            public function store($key, $value, $ttl = null)
            {
                try {
                    if (ApcuFunctions::isRegistered()) {
                        return Cache::store('apcu')->store($key, $value, $ttl);
                    }
                } catch (\Exception $e) {
                    \Log::error("APCu polyfill failed: " . $e->getMessage());
                }
                return Cache::store('file')->store($key, $value, $ttl);
            }
        };
    });
    

Workflows

  1. Shared Hosting Workflow:

    • Enable polyfill in .env for shared hosting environments.
    • Use apcu cache driver for non-critical operations (e.g., sessions, config).
    • Monitor performance with Laravel Telescope.
  2. Local Development Workflow:

    • Install polyfill in Docker containers where ext-apcu is unavailable.
    • Use APCU_POLYFILL=true in .env for consistency with production.
  3. Migration Workflow:

    • Phase 1: Enable polyfill for shared hosting users.
    • Phase 2: Gradually migrate critical paths to Redis.
    • Phase 3: Remove polyfill once Redis is fully adopted.

Integration Tips

  • Laravel Events: Listen to CacheStoredEvent to log polyfill usage:

    Cache::store('apcu')->extend(function ($store) {
        $store->listen(function ($event) {
            if (ApcuFunctions::isRegistered()) {
                \Log::debug("Polyfill stored: {$event->key}");
            }
        });
    });
    
  • Testing: Mock polyfill in PHPUnit:

    public function testApcuPolyfill()
    {
        if (!extension_loaded('apcu')) {
            ApcuFunctions::register();
        }
        Cache::put('test', 'value');
        $this->assertEquals('value', Cache::get('test'));
    }
    
  • Performance Isolation: Restrict polyfill to non-critical cache stores:

    // config/cache.php
    'stores' => [
        'apcu' => [
            'driver' => 'apcu',
            'use_polyfill' => env('APCU_POLYFILL', false),
        ],
        'redis' => ['driver' => 'redis'], // Keep critical paths on Redis
    ],
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • Polyfill is 5–50× slower than native APCu. Avoid for high-frequency operations (e.g., request caching).
    • Fix: Use Redis/Memcached for performance-critical paths.
  2. Memory Limits:

    • Polyfill stores data in PHP memory, risking Allowed memory exhausted for large caches.
    • Fix: Monitor memory usage with memory_get_usage() and limit cache size.
  3. Serialization Issues:

    • Complex objects (e.g., closures, resources) may fail to serialize/deserialize.
    • Fix: Use serialize()/unserialize() or fall back to file cache:
      Cache::store('file')->put($key, serialize($value));
      
  4. Unsupported Functions:

    • Some apcu_* functions (e.g., apcu_cas(), apcu_delete()) may not be fully supported.
    • Fix: Audit usage with grep -r "apcu_" and refactor unsupported calls.
  5. Process-Local Scope:

    • Polyfill data is not shared across processes (unlike Redis).
    • Fix: Use Redis for distributed caching.
  6. Opcode Caching:

    • Polyfill does not support opcache functionality.
    • Fix: Ensure opcache is enabled natively if needed.

Debugging

  1. Check Polyfill Activation:

    if (ApcuFunctions::isRegistered()) {
        \Log::info('APCu polyfill is active');
    }
    
  2. Log Cache Operations:

    Cache::store('apcu')->extend(function ($store) {
        $store->listen(function ($event) {
            \Log::debug("Cache event: {$event->key} - {$event->action}");
        });
    });
    
  3. Memory Usage:

    $memory = memory_get_usage(true);
    \Log::info("APCu polyfill memory usage: " . ($memory / 1024 / 1024) . "MB");
    

Tips

  1. Environment-Specific Configuration: Use .env to toggle polyfill:

    # .env.shared-hosting
    APCU_POLYFILL=true
    
  2. Fallback Cache Driver: Implement a hybrid driver:

    Cache::extend('hybrid', function ($app) {
        return new class($app) extends \Illuminate\Cache\Repository {
            public function store($key, $value, $ttl = null)
            {
                try {
                    if (ApcuFunctions::isRegistered()) {
                        return Cache::store('apcu')->store($key, $value, $ttl);
                    }
                } catch (\Exception $e) {
                    \Log::error("APCu polyfill failed: " . $e->getMessage());
                }
                return Cache::store('redis')->store($key, $value, $ttl);
            }
        };
    });
    
  3. Monitor Polyfill Usage: Track polyfill activation in production:

    if (ApcuFunctions::isRegistered()) {
        \App\Models\CacheLog::create([
            'driver' => 'apcu_polyfill',
            'ip' => request()->ip(),
        ]);
    }
    
  4. Benchmark Before/After: Compare performance with native APCu:

    $start = microtime(true);
    Cache::put('benchmark', 'value');
    $time = microtime(true) - $start;
    \Log::info("Cache operation time: {$time}s");
    
  5. Cleanup Old Data: Polyfill may retain stale data. Clear cache periodically:

    if (ApcuFunctions::isRegistered()) {
        ApcuFunctions::apcu_clear_cache();
    }
    
  6. Avoid in CI/CD: Disable polyfill in CI/CD pipelines where ext-apcu is available:

    # .env.ci
    APCU_POLYFILL=false
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi