Weave 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

Opcache Dashboard Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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:

  1. Read 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.
  2. Confirm the namespace before writing code. 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.
  3. Decide whether this is a Laravel package at all. It is a Symfony bundle — Laravel has no bundle registration, no 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:
    • a small sidecar Symfony 6.4/7.1 app whose only job is to serve the OPcache dashboard for the same PHP-FPM pool, or
    • harvesting the status logic — the bundle is mostly a thin wrapper over opcache_get_status() / opcache_reset(), so copy the controller + Twig view into a Laravel route and Blade view, or
    • a custom Artisan command if all you actually want is the numbers.

Minimal 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.

Implementation Patterns

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.

Gotchas and Tips

  • Version 2.0.0 is literally the initial commit. No migration guide, no changelog depth, likely incomplete docs and unstable internal namespaces. Pin an exact version ("xact/...": "2.0.0") and expect breaking changes in 2.0.x while it stabilises.
  • The rename is the migration. Every reference to the old bundle class, service ID, route name, Twig namespace and config key breaks silently or at container compile time. Do a repo-wide grep for the old name; don't rely on deprecation warnings — there are none in a hard rename.
  • Folder restructure ≠ API compatibility. Even where class names survive, PSR-4 paths, template locations (@Bundle/... Twig namespaces) and config tree keys moved. Clear var/cache after upgrading; stale container caches mask the real error.
  • Symfony 6.4/7.1 constraint is a hard wall. If your Laravel app is on an older Symfony component set (Laravel 9 pulls Symfony 6.0–6.2), composer will refuse to install the bundle alongside it. This is the strongest argument for the sidecar or port-it approach.
  • OPcache is per-process and per-SAPI. The dashboard reports only the FPM worker that served the request. With 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().
  • Dashboard caching. If you put the dashboard behind a response cache or CDN, you'll serve stale stats and, worse, leak internals to anonymous users. Mark it no-store.
  • Security surface. The dashboard reveals absolute file paths, script counts and deploy timing — useful reconnaissance. Always behind auth, ideally IP-allowlisted, and never enabled by default in production.
  • Extension points to watch for in 2.x: the bundle's data provider/collector service (decorate it to add your own metrics) and its route loader. Confirm both still exist after the restructure before building on them — that's the cheapest place to inject app-specific data.
  • Debugging tips: if the page is blank, check the Twig namespace first (classic post-restructure break). If stats are empty, confirm 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.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource