ForgeDebugBar

A development-time toolbar your app shows at the bottom of every HTML page so you can inspect a request while it happens — memory, timing, database queries, routes, sessions, and more.

Overview

ForgeDebugBar is the debugging companion for your app. When enabled, it automatically injects a slim, tabbed toolbar into each HTML response. You keep your markup untouched — the bar is appended just before </body> along with its own CSS and a small bit of JavaScript.

It's built around collectors: small pieces of code, each responsible for one slice of data (memory, request time, messages, route, session, and — when the router capability is around — timeline, views, exceptions, and database queries). Collectors feed the tabbed panels, so you see what happened on the request you're looking at.

Framing: this is a tool for the person building the app, active only while you develop. It never ships to users — when APP_DEBUG is off, the bar simply doesn't appear.

Installation

php forge.php package:install-module --module=forge-debug-bar

The capability needs the router and view capabilities present, and it links its public assets (the CSS and JS the bar uses) during installation:

php forge.php asset:link --type=module --module=forge-debug-bar

This makes the assets available at /assets/modules/forge-debug-bar/ so the injected toolbar can load them.

When the Bar Shows

The bar only appears when both of these are true:

  • APP_DEBUG is enabled in your environment.
  • forge_debug_bar.enabled is true (the default).

On top of that, injection is careful about what it touches. It skips:

  • Responses whose Content-Type isn't HTML (for example JSON or files).
  • Bodies that don't contain a </body> tag.
  • Responses that look like a fragment, such as a leading {"html":.

The Bar & Tabs

The toolbar has a compact header that shows the essentials at a glance, then a set of tabs you can click to open full panels:

Metric Shows
Request time Total execution time for the request, in milliseconds
Memory Current memory usage (e.g. 14.30 MB)
PHP version The PHP runtime the request ran on

The Resources tab (memory panel) is always registered. The rest open up when metrics are enabled:

  • Overview — request details
  • Console — your custom debug_log() messages
  • Errors — caught exceptions
  • Database — executed queries
  • Router — the matched route
  • Templates — rendered views
  • State — session data
  • Timeline — timing events

Each tab shows a small count badge when it has data, so you can spot at a glance which panels have something interesting.

Hub integration: when the Hub is present, the latest request's data is also stored so you can review it from the Hub's Debug Bar panel rather than digging through each page response.

Collectors

Collectors are the guts of the bar. Each is a named unit that returns the data for one panel when asked. A few of the built-in ones are always active:

Collector What it reports
memory Current / used / peak usage and the percent of your memory limit
time Request execution time from app start
messages Custom messages you logged with debug_log()
request / session / route Request details, session contents, and the matched route (metrics on)

When metrics are enabled, the bar also adds cross-module collectors provided by the router capability — timeline, views, exceptions, and database queries — but only for the ones actually available in your app. If a collector isn't present, its tab simply stays empty.

For custom needs, you can drop in your own collector by pairing a name with a callable that returns its data:

$bar = \Modules\ForgeDebugBar\DebugBar::getInstance();

$bar->addCollector('my-plugin', function () {
    return ['calls' => MyService::callCount()];
});

Custom Messages

The most common way to use the bar from your own code is the debug_log() helper. It records a message (with an optional label) that shows up in the Console tab on the current request:

debug_log('Order #123 placed', 'info');
debug_log($shippingTotal, 'amount');

Messages carry a label (default info) and a timestamp, so you can follow the sequence of events within a request.

A small formatBytes() helper is also available for turning byte counts into readable units (B, KB, MB, GB) in your own output.

Configuration

Two environment variables control the bar:

Variable Default Effect
FORGE_DEBUG_BAR_ENABLED true Master on/off (must also have APP_DEBUG)
FORGE_DEBUG_BAR_METRICS true When false, only memory/time/messages and the Resources tab run

Turning metrics off is a quick way to keep the bar lightweight — the request, session, and route collectors plus the cross-module collectors and their tabs are simply skipped, along with the session-merge work that surfaces exceptions.

Safe in Production

Because the bar is gated on APP_DEBUG, a production environment with debugging off never renders it and never runs its collectors. Its public assets (a CSS file and a small JS file) can stay linked without impacting real users.

Remember: keep APP_DEBUG off in production. The debug page your error handler shows, and this bar, both rely on that flag — exposing stack traces or request details to visitors would be a mistake.