zappzarapp/devtoolbar

In-app developer toolbar for PHP applications: timeline, query analyzer, HTTP/cache collectors, exception tracking, request history. Ships the JS UI as a bundled asset (symfony/web-profiler-bundle pattern).

Maintainers

Package info

github.com/marcstraube/zappzarapp-php-devtoolbar

pkg:composer/zappzarapp/devtoolbar

Transparency log

Statistics

Installs: 59

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-07-23 21:07 UTC

This package is auto-updated.

Last update: 2026-07-23 22:09:42 UTC


README

In-app developer toolbar for PHP applications. Renders a mini-bar overlay with collectors for queries, HTTP requests, cache operations, exceptions, timeline phases, and request history, with N+1 detection and configurable performance alerts.

The JavaScript UI ships as a pre-built asset of this PHP package (the symfony/web-profiler-bundle pattern): composer require is all a consumer needs — no Node toolchain, no npm install.

Requirements

  • PHP 8.4+
  • monolog/monolog ^3.0 — MessageCollector extends AbstractProcessingHandler
  • zappzarapp/security ^1.0 — supplies the per-request CSP nonce for the injected <script> / <style> tags

Installation

composer require --dev zappzarapp/devtoolbar

Install it as a dev dependency. The toolbar is a development-time surface and its activation guard is fail-closed (see Activation).

Usage

Boot the toolbar at the top of your front controller and register an output buffer callback that injects the toolbar HTML before </body>:

use Zappzarapp\DevToolbar\DevToolbar;
use Zappzarapp\DevToolbar\Guard\DevToolbarGuard;

require __DIR__ . '/../vendor/autoload.php';

if (DevToolbarGuard::isEnabled()) {
    $toolbar = DevToolbar::getInstance();
    $toolbar->boot();

    // injectToolbar() runs when the buffer is flushed — a safe alternative
    // to echoing from a shutdown function.
    ob_start([$toolbar, 'injectToolbar']);
}

// ... dispatch the request and render the response as usual ...

boot() and injectToolbar() are both no-ops when the guard reports the toolbar as disabled, so the two calls above are safe to leave in place; guard them with isEnabled() only to avoid the output-buffer overhead in production.

Activation

DevToolbarGuard::isEnabled() is fail-closed — the toolbar stays off unless a development environment is proven. The decision, in order:

  1. ENABLE_DEV_TOOLBAR — an explicit on/off switch. true (any case) or 1 enables; anything else, including typos, disables.
  2. Otherwise the first set of APP_ENV then ENV must equal one of dev, development, local, test, testing (case-insensitive).
  3. A missing or unrecognized environment is treated as production → disabled.

The guard also disables under the CLI SAPI and for AJAX requests. Values are read via getenv() with an $_ENV / $_SERVER fallback, so PHP-FPM setups running with clear_env=yes do not silently fail open.

CSP nonce

Injected inline <script> / <style> tags carry the per-request nonce from zappzarapp/security's NonceRegistry — there is no unsafe-inline requirement. If your application generates its own nonce, hand it to the toolbar before boot():

$toolbar->setNonce($cspNonce);

Feeding collectors

boot() registers the default collectors and starts them. Instrument your application by fetching a collector and recording operations as they happen:

$queries = $toolbar->getCollector('queries');
$queries?->trackQuery($sql, $bindings, $durationMs);

Available collector names: request, queries, http, cache, messages, exceptions, timeline, history. See the classes under Zappzarapp\DevToolbar\DataCollectors for each collector's tracking API.

Security

The toolbar exposes request internals (SQL, request/response data, exception backtraces) to anyone who can render it. Never enable it in production, and treat any environment reachable beyond localhost as production. See SECURITY.md for the full model.

License

MIT — see LICENSE.