symfony/polyfill-apcu
Symfony Polyfill / APCu brings the apcu_* functions and the APCuIterator class to projects still running the legacy APC extension, letting older code use APCu without changes. Lightweight compatibility layer from Symfony, released under the MIT license.
Architecture fit
apcu_* functions and APCuIterator by delegating to the legacy apc_* extension. It operates at the PHP global-function layer, beneath Laravel's Cache facade and Illuminate\Cache\ApcuStore.files autoload and only defines functions that aren't already defined. Any plan describing registration in AppServiceProvider, or a per-store use_polyfill config key, is describing work this package does not do — that scaffolding would be custom-built and owned by us.ext-apc is present and ext-apcu is absent, or where code calls apcu_* directly rather than through the Cache contract. The addressable population inside a supported Laravel install base — 5.1 through 12 all require PHP ≥ 5.5.9, and APC does not run there — is approximately zero.Integration feasibility
composer require symfony/polyfill-apcu, ~1.5 MB, MIT, no transitive dependencies). That is the only genuinely low-friction part.CACHE_DRIVER=apcu just works" — does not survive scrutiny. extension_loaded('apcu') stays false after the polyfill loads. Laravel's CacheManager guards the apcu driver on that extension check and throws; third-party packages gating on extension_loaded('apcu') or apcu_enabled() bypass the polyfill too. It satisfies function-existence but not capability detection — and capability detection is the common pattern.apc nor apcu is present, calls resolve to the polyfill's definitions, which invoke undefined apc_* functions — a fatal Error, not a graceful fallback. This contradicts any "safety net / graceful degradation" framing.\Symfony\Polyfill\Apcu\ApcuFunctions::register() / isRegistered()) does not exist in the package. Acceptance criteria, test cases, and rollout steps written against it are invalid and must be rewritten before commitment.Technical risk
artisan commands, and cache warmers see empty caches while web requests see populated ones. Divergence between workers is a debugging tax, not a defect we can fix.Key questions
ext-apcu, ext-apc, neither? If "neither" is material, this package solves nothing and the initiative closes.apcu_* directly — our app, a vendor package, or a config value? What breaks if we refactor that call site instead of shimming it?Cache contract and a driver change, not a function polyfill.ext-apcu in the build image; move affected stores to file/database/redis)? That delta is the real business case.Stack fit
Cache → apcu driver path if we also bypass Laravel's extension guard via a custom Cache::extend registration that skips ensureExtensionIsLoaded. That is unsupported-path engineering; it is our code, our bug, and outside the vendor's support envelope.apcu_* directly and cannot be upgraded. In that case the polyfill is a legitimate stopgap — but only on hosts where ext-apc exists, which in practice means hosts we should already be migrating off.Migration path
ext-apcu is configuration, not a dependency: switch the affected store in config/cache.php and set CACHE_STORE (file/database locally, redis in production). That one-line change is the real migration, measured in hours, not weeks.apcu_* call exists, wrap it behind Laravel's Cache contract (Cache::store(...)) so the backend becomes an environment decision. This is the durable refactor and it removes the need for the polyfill entirely.Compatibility
php -m | grep -i apc distinguishes apc from apcu from neither, and only the first makes the polyfill functional.extension_loaded('apcu') and apcu_enabled() will both report absent; any package or Laravel internals that check capability rather than function existence will behave as if uninstalled.APCuIterator exists, but iterates an empty/absent store unless apc_* is backed by real shared memory. Functional smoke tests must assert on stored values, not on class/function existence.Sequencing
composer why symfony/polyfill-apcu, grep -rn "apcu_" app/ config/, php -m | grep -i apc per environment.apcu_* call site exists and is load-bearing: refactor to the Cache contract.Maintenance
Support
Scaling
Failure modes
Error when neither APC nor APCu is present — the polyfill proxies to undefined apc_*. This is the failure mode most likely to reach production, and it is the opposite of the graceful degradation the shim is often bought for.CacheManager throws on the apcu driver because extension_loaded('apcu') remains false — the driver simply won't resolve.Ramp-up
apcu_* is never load-bearing for correctness."Cache::store('file') locally, Cache::store('redis') in production, and treat APCu as a lossy per-process optimisation only.apcu_* for correctness; every environment has a cache driver that works without ext-apcu; the package is either absent from composer.json or recorded as knowingly inert.How can I help you explore Laravel packages today?