matthimatiker/opcache-bundle
Symfony bundle for managing and monitoring PHP OPcache from your application. Provides convenient integration for checking cache status, clearing OPcache, and exposing cache statistics, helping deployments and configuration changes run smoothly.
Architecture fit. Low as a dependency, moderate as source material. Despite the "Laravel/PHP package" framing, matthimatiker/opcache-bundle is a Symfony bundle: it registers a DataCollector into the Symfony Profiler and renders a toolbar panel via Twig. Laravel consumes individual Symfony components, not FrameworkBundle, Profiler, or the Twig toolbar pipeline, so there is no registration path for the bundle's service definitions, compiler passes, or Resources/views templates. composer require yields an inert vendor directory at best. The reusable asset is narrow and framework-agnostic: the logic wrapping opcache_get_status() / opcache_get_configuration() and deriving hit rate, memory used/free, cached and wasted script counts, and restart counters — roughly a few hundred lines. Everything framing that logic (bundle class, DI extension, Twig views) must be discarded.
Integration feasibility. Feasible only as a port, not an install. A TPM should scope this as a 1–3 day internal task for a mid-level engineer: a ServiceProvider, a guarded route or Blade partial, and optionally a Laravel Debugbar collector (BarCollectorInterface) so OPcache metrics sit alongside queries and request data. Because Laravel Debugbar or Telescope is already present in most estates, the honest framing is that this package represents a feature, not a product, in a Laravel context.
Technical risk. High, concentrated in dependency and staleness:
symfony/* constraints target the Symfony 2.x/3.x era; Laravel 9+ requires Symfony 6.x/7.x. Composer resolution will fail or force an untenable downgrade of core Laravel components. Do not attempt to satisfy it.local.Key questions for the requesting team.
Stack fit. Target modern Laravel (10/11) on PHP 8.1+. Use only native functions — opcache_get_status(false), opcache_get_configuration(), opcache_reset() — with zero third-party runtime dependencies. Ship as an internal package (internal/opcache-inspector) or, more cheaply, a single class plus a Blade view inside the app.
Migration path (do not install the bundle).
| Step | Action | Effort |
|---|---|---|
| 1 | Vendor-in the collector extraction logic as an internal class (MIT permits; retain attribution) | 0.5d |
| 2 | Register a ServiceProvider; bind a singleton OpcacheStatusRepository |
0.5d |
| 3 | Expose via a local-only route behind auth + environment middleware, or as a Debugbar collector |
0.5–1d |
| 4 | Add an opcache.enable guard and a graceful "OPcache disabled" render |
0.25d |
| 5 | Document CLI/FPM divergence and the opcache.enable_cli requirement |
0.25d |
Compatibility caveats to validate in the spike.
opcache_get_status() returns false when OPcache is disabled and is blocked entirely by opcache.restrict_api; the UI must degrade, not throw.php artisan opcache:status shows an empty or CLI-only cache unless opcache.enable_cli=1 — the single most common source of "the tool is broken" tickets.scripts key can hold tens of thousands of entries on a large app. Always call opcache_get_status(false) and page/aggregate; a naive dump is a memory and response-size incident.restart_pending / restart_in_progress flags detect config changes requiring a reload — surface them explicitly.Sequencing. Run a strict, timeboxed spike (≤2 days) answering one question: does OPcache hit-rate and memory data change any decision we make? If the answer is "we want to eyeball it occasionally," ship the guarded route and stop. If it is "we want alerting on cache churn," skip this entirely and go to an APM vendor — that path has support, fleet aggregation, and no fork obligation.
Maintenance. Treat the package as unmaintained source material, not a dependency. Adding it as a Composer requirement transfers an indefinite fork obligation to the team for a read-only dev-time panel. The code volume is small enough that a fork is survivable, but it will never be someone else's job to fix. Budget ~0.5 day/year for PHP-version upkeep plus the initial port.
Support. No vendor, no SLA, 22 stars, 0 dependents — the ecosystem blast radius is itself a signal that nobody has stress-tested this against modern runtimes, and there is no security disclosure channel. Acceptable for a local-only diagnostic; not acceptable anywhere near production traffic.
Scaling. OPcache is per-process and per-node. This panel shows exactly one PHP instance on one host: behind a load balancer it is a random-sample view, and on Octane it reflects a single node's workers, with preloading making the "scripts" picture unfamiliar. There is no aggregation, history, alerting, or time-series. It answers "what does this box think right now," not "is caching healthy across the fleet."
Failure modes.
| Mode | Symptom | Mitigation |
|---|---|---|
OPcache disabled / restrict_api |
Collector returns false, panel errors |
Explicit null-guard + "disabled" state |
| CLI vs FPM confusion | Empty cache shown from Artisan | Document; set opcache.enable_cli deliberately |
Large scripts array |
Memory spike, slow response | opcache_get_status(false), aggregate server-side |
| Production exposure | Filesystem paths and config leaked | Env gate + auth middleware, deny-by-default |
| Stale key assumptions | Wrong memory/hit-rate math post-8.0 | Unit-test against fixture payloads per PHP minor |
| Unpinned drift | Composer conflict on symfony/* |
Never add as a requirement; vendor the code |
Ramp-up. Low. Any Laravel developer can read the collector and reproduce it, and a TPM needs roughly one paragraph of context to understand what the panel shows — and, more importantly, what it does not (no history, no fleet view, no alerting). The risk is not onboarding cost; it is the false confidence that a green-looking hit-rate panel on one dev box constitutes performance observability.
TPM leverage and recommendation. A score of 2.19 is consistent with the evidence. Do not adopt as a dependency. Either port ~200 lines of collector logic into a local-gated Laravel route or a Debugbar collector (if dev-time inspection is the real need), or route the requirement to an APM vendor (if production visibility is the real need). The package's genuine value to a TPM is twofold: as a reference implementation and checklist of OPcache metrics worth tracking, and as a roadmap forcing function — the data it surfaces (hit rate, memory used/free, wasted scripts, restart counters) is exactly what separates a php.ini tuning sprint from app-level caching work, and it draws a clean tooling boundary between dev/staging introspection and a paid APM decision. Use it to make that call, not as software to run.
How can I help you explore Laravel packages today?