xactsystems/opcache-dashboard
A dashboard package for monitoring and managing PHP OPcache. View cache statistics, memory usage, hit rates, and cached scripts, then clear or reset the cache from a simple web interface—helpful for debugging performance and keeping your opcode cache healthy.
V2.0.0 is a breaking rename plus a fresh codebase ("V2 initial commit"), so treat this as a new package rather than an upgrade. Three things changed at once: the package/bundle name (XactOPCacheDashboardBundle), the folder layout (PSR-4 autoload paths, config, routes and templates all moved), and the Symfony constraint (6.4 / 7.1 only).
First steps:
composer.json, not the release note. The note is one line — the real contract is the name, autoload.psr-4, require (PHP and symfony/* constraints) and the bundle class FQCN. Confirm PHP 8.1+ and that your Symfony-side hosts are on 6.4 LTS or 7.1; anything on 5.4/6.0–6.3 is cut off.V2 initial commit + rename usually means the old Xact\... FQCN is gone. Grep for the old bundle class in your config/bundles.php (Symfony) or service config and replace it wholesale.config/bundles.php, no DI extension class loading. In a Laravel app you cannot composer require and get a dashboard. Your realistic first use case is one of:
opcache_get_status() / opcache_reset(), so copy the controller + Twig view into a Laravel route and Blade view, orMinimal Laravel-side equivalent to validate the concept before adopting anything:
Route::get('/_ops/opcache', function () {
abort_unless(app()->environment('local') || auth()->user()?->isAdmin(), 403);
return response()->json([
'enabled' => function_exists('opcache_get_status'),
'status' => opcache_get_status(false) ?: null,
'config' => opcache_get_configuration()['directives'] ?? [],
]);
})->middleware('auth');
If that gives you what you need, you likely don't need the bundle.
Sidecar Symfony app (closest to intended use). Register the renamed bundle in config/bundles.php, import its routing (prefix it, e.g. /_xact/opcache), and point it at the same FPM pool you want to inspect. Import its config and override the dashboard path and any polling interval there; V2's folder restructure means published config/route/template paths from v1 no longer apply — re-publish rather than copying old files.
Port into Laravel as a guarded route. Keep the bundle's computation (hit rate, memory usage, cached/uncached script lists, restart-pending flags) and swap Twig → Blade. Wrap in a middleware group with auth + an explicit admin gate, and register the route only when app()->environment() !== 'production' or behind a feature flag.
Scheduled health check instead of a dashboard. For day-to-day work the dashboard is a debugging tool, not monitoring. A scheduled command that emits metrics is more useful:
// app/Console/Commands/OpcacheHealth.php
$s = opcache_get_status(false);
$used = $s['memory_usage']['used_memory'];
$free = $s['memory_usage']['free_memory'];
$hitRate = $s['opcache_statistics']['opcache_hit_rate'];
// push to your metrics backend, alert on $hitRate < 95 or restart_pending
Correlate with Laravel's own tooling. Once you know the OPcache hit rate, the follow-on questions are "which deploy invalidated it" and "which route is slow" — Telescope/Pulse answer those. Use the OPcache data to explain why latency jumped after a release (validate_timestamps=0 + no reset = stale code; restart_pending = memory exhausted).
Reset/invalidate carefully. If the bundle exposes a reset action, do not wire it to a public route. In Laravel, gate it behind auth + can: and prefer opcache_reset() from a deploy hook or php artisan on the host, not over HTTP.
"xact/...": "2.0.0") and expect breaking changes in 2.0.x while it stabilises.@Bundle/... Twig namespaces) and config tree keys moved. Clear var/cache after upgrading; stale container caches mask the real error.pm = dynamic and N workers you're seeing one sample. CLI has a separate OPcache (opcache.enable_cli), so artisan output will disagree with web output — both are "correct."opcache.restrict_api silently disables opcache_reset()/opcache_invalidate() from web requests if set. Symptom: the reset button does nothing, no exception. Check opcache_get_configuration().no-store.opcache.enable=1 and that you're not behind a proxy hitting a different pool. If numbers look frozen, opcache.validate_timestamps=0 is doing its job — deploy with a reset.How can I help you explore Laravel packages today?