Documentation
Everything you need to integrate DebugPHP into your project — from installation to self-hosting your own server.
On this page
Installation
DebugPHP is installed via Composer. Requires PHP 8.1 or higher and the ext-curl extension. Works with any PHP framework — Laravel, Symfony, WordPress — or plain PHP.
composer require callmeleon167/debugphp --dev
--dev. DebugPHP should never run in production. The package has zero runtime dependencies.Quickstart
After installation you only need two lines to get started. Call init() once at your application entry point, then call send() anywhere in your code.
use DebugPHP\Debug;
// Initialize once — typically in bootstrap or index.php
Debug::init('your-session-token');
// Send anything — DebugPHP handles the rest
Debug::send('Hello DebugPHP!');
Debug::send($user);
Debug::send($request->all());
Open your Dashboard in the browser and your data appears in real-time as each request is processed.
Configuration
Debug::init(string $token, array $options = []): void
Pass an optional options array as the second argument to init() to override defaults.
Debug::init('your-session-token', [
'host' => 'https://dashboard.debugphp.dev',
'timeout' => 5,
'enabled' => true,
]);
| Option | Type | Default | Description |
|---|---|---|---|
| host | string | debugphp.dev | Server URL that receives the debug data |
| timeout | int | 3 | cURL request timeout in seconds |
| enabled | bool | true | When false, all Debug calls are silently ignored — no HTTP requests, zero overhead |
Tie enabled to an environment variable so DebugPHP is automatically disabled outside of local dev:
Debug::init('session-token', [
'enabled' => getenv('APP_DEBUG') === 'true',
]);
init() also sends environment data (PHP version, SAPI, OS, etc.) to the dashboard toolbar automatically.
Debug::send()
Debug::send(mixed $data, string $label = ''): Entry|null
The core method. Accepts any single value — strings, integers, floats, booleans, arrays, objects, and exceptions. An optional label string can be passed as the second argument.
Returns an Entry object for optional fluent chaining (->color(), ->type()), or null if DebugPHP is not initialized, disabled, or paused. The HTTP request is dispatched when the Entry goes out of scope, ensuring chained calls are applied before transmission.
// Any scalar value
Debug::send('User created successfully');
Debug::send($userId);
// Arrays and objects are rendered as a var_dump-style tree
Debug::send($user->toArray());
Debug::send($response, 'API Response');
// Exceptions render class, message, file, line, and a condensed stack trace
try {
$service->process();
} catch (\Throwable $e) {
Debug::send($e);
}
Explicit dispatch with Entry::send()
Entry->send(): self
By default, the Entry is dispatched automatically when the object is destroyed (__destruct). If you need to guarantee the entry is sent at a specific point — for example before a long-running process or an exit call — use ->send() to dispatch immediately. Calling it multiple times is safe; only the first call triggers the HTTP request.
// Force immediate dispatch before a long-running task
Debug::send('Starting import…', 'Import')?->color('blue')->send();
$importer->run(); // entry is already on the dashboard
// Useful before exit/die to ensure nothing is lost
Debug::send($result, 'Final')?->send();
exit;
Error capture
DebugPHP can automatically capture PHP errors, warnings, notices and deprecations and forward them to the dashboard as structured table entries.
Use Debug::captureErrors() to register the error handler and shutdown function. The captured data includes the error message, file path, line number and a stack trace where available.
use DebugPHP\Debug;
Debug::init('your-session-token');
Debug::captureErrors(E_ALL);
// Trigger a warning or notice ...
trigger_error('Test warning', E_USER_WARNING);
| Captured field | Description |
|---|---|
| Message | The PHP error message. |
| File | File name and line number. |
| Path | Absolute file path where the error occurred. |
| Stack trace | Backtrace frames excluding internal DebugPHP package calls. |
If a fatal error occurs, DebugPHP captures it on shutdown and sends a table entry without a trace, since PHP cannot provide a backtrace in that case.
Log levels
DebugPHP supports all 8 RFC 5424 log levels for standardized severity classification.
| Level | Method | Color | Description |
|---|---|---|---|
emergency |
Debug::emergency() |
Red | System is unusable |
alert |
Debug::alert() |
Red | Action must be taken immediately |
critical |
Debug::critical() |
Red | Critical conditions |
error |
Debug::error() |
Red | Runtime errors |
warning |
Debug::warning() |
Orange | Unexpected but not an error |
notice |
Debug::notice() |
Blue | Normal but significant events |
info |
Debug::info() |
Gray | General informational messages |
debug |
Debug::debug() |
Purple | Detailed diagnostic information |
Usage Example
Debug::emergency('Database connection lost');
Debug::alert('Disk space critically low');
Debug::critical('Payment gateway timeout');
Debug::error($exception);
Debug::warning('Deprecated function called');
Debug::notice('User login from new location');
Debug::info('Background job completed');
Debug::debug($requestPayload);
Parameters
| Parameter | Type | Description |
|---|---|---|
$data |
mixed |
The data to send to the dashboard — supports all PHP types. |
$label |
string |
Optional label for categorization. Defaults to the level name (e.g., "Error", "Warning"). |
Debug::send() with pre-configured colors and types. You can still override these by calling ->color() or ->type() on the returned Entry object.
Labels & Colors
Entry->color(string $color): static
Entry->type(string $type): static
Both methods return the same Entry instance and can be freely chained. color() sets the accent bar color in the dashboard. type() controls the badge label shown on the entry — common values are info, sql, error, success, timer, but any string is accepted and displayed as-is. Invalid color names are silently ignored.
// No label — defaults to "info"
Debug::send($data);
// Custom label for categorization
Debug::send($query, 'SQL');
Debug::send($response, 'API Response');
// Combine label with color and type
Debug::send($result, 'Query')->color('purple')->type('sql');
| Color | Use case |
|---|---|
| red | Errors, exceptions |
| blue | SQL queries, HTTP requests |
| green | Success states, cache hits |
| orange | Warnings, slow paths |
| purple | Database, auth |
| gray | Verbose / low-priority output |
Metrics
Debug::metric(string $key, ?string $value = null): void
Metrics are displayed as live chips in the dashboard toolbar — always visible regardless of scroll position. Ideal for request-level context you always want at a glance: current template, memory usage, authenticated user, query count.
// Key + value — displayed as "Memory: 4.2 MB"
Debug::metric('Memory', memory_get_usage(true) / 1024 / 1024 . ' MB');
Debug::metric('Template', 'home.php');
// Key only — displayed as "Maintenance Mode"
Debug::metric('Maintenance Mode');
Sending the same key again updates the value live in the toolbar (UPSERT behaviour). If a metric key is not sent in a subsequent PHP request it is automatically removed from the dashboard. This works via a request_id generated fresh on every Debug::init() call — the server detects stale keys and pushes a removal event to all connected dashboards.
request_id principle: when a new PHP request starts, all previous log entries are automatically cleared.Timer
Debug::startTimer(string $name): void
Debug::stopTimer(string $name): float|null
Measure execution time of any code block without a dedicated profiler. stopTimer() automatically sends the result to the dashboard and returns the elapsed time in milliseconds as a float, or null if the given name was never started. Multiple independent timers can run simultaneously.
Debug::startTimer('render');
// Your slow operation
$template->render();
$elapsed = Debug::stopTimer('render');
// Sends "render: 145.23ms" to the dashboard and returns 145.23
Tables
Debug::table(array $rows, ?array $headers = null): ?Entry
Display structured data as a formatted table in the dashboard. Column headers are auto-detected from the keys of the first row. Pass an explicit $headers array as the second argument to override them.
// Headers auto-detected from row keys: "name", "role"
Debug::table([
['name' => 'Leon', 'role' => 'Developer'],
['name' => 'Sarah', 'role' => 'Designer'],
]);
// Explicit column headers
Debug::table($rows, ['Full Name', 'Role']);
Clear & Pause
Debug::clear(): void
Debug::pause(): void
Debug::resume(): void
clear() sends a clear command to the dashboard, removing all current log entries from the session. Useful at the start of a request to keep the view clean. pause() and resume() toggle output locally — while paused, all Debug calls are silently ignored without making any HTTP requests.
Debug::clear(); // Wipe all entries in the dashboard session
Debug::pause(); // Silence all subsequent Debug calls
Debug::send('This will not appear');
Debug::resume(); // Re-enable output
Debug::send('This will appear');
Sessions
Every debug session has a unique token that ties your PHP requests to a specific dashboard view. You can run multiple sessions simultaneously — ideal for team collaboration or debugging multiple projects at once without output mixing.
SESSION_LIFETIME_HOURS environment variable on your server.Create a new session from the dashboard by clicking + New Session. Each session token is a unique string you pass to Debug::init(). Anyone with access to your dashboard URL and the same token can observe the same stream — useful for pair debugging.
// Project A
Debug::init('token-project-a');
// Project B (separate browser tab with its own session)
Debug::init('token-project-b');
Self-Hosted
Keep your debug data entirely on your own infrastructure.
git clone https://github.com/CallMeLeon167/debugphp-server.git
cd debugphp-server
composer install
php -S localhost:8787
Running via Docker
Alternatively, you can run the server via Docker.
git clone https://github.com/CallMeLeon167/debugphp-server.git
cd debugphp-server
docker compose up
Debug::init('your-session-token', [
'host' => 'http://localhost:8787',
]);
Debug::init('your-session-token', [
'dockerized' => true,
]);
Server configuration
The self-hosted server is configured via a .env file in the project root. The setup wizard creates this file automatically, but you can edit it manually at any time. All values have sensible defaults.
# Storage STORAGE_PATH=data # Session SESSION_LIFETIME_HOURS=24 SESSION_ID=
| Variable | Type | Default | Description |
|---|---|---|---|
| STORAGE_PATH | string | data | Path to the directory where debug data is stored |
| SESSION_LIFETIME_HOURS | int | 24 | How long a debug session stays active before it expires and is automatically cleaned up |
| SESSION_ID | string | (empty) | Optional static session ID. When set, the server uses this fixed ID instead of generating random ones. Leave empty for random session mode. Ideal for team debugging or persistent sessions across server restarts. |
.env values, restart your PHP process (or PHP-FPM) for the changes to take effect. The setup wizard can be re-run by setting ALLOW_SETUP = true in setup/index.php.Framework support
DebugPHP provides first-class framework integrations via Debug::framework(). Call it once after Debug::init() to automatically hook into your framework's logging pipeline — no manual instrumentation required.
Laravel
The Laravel integration hooks into Laravel's underlying logging driver. All log entries written via Log::info(), Log::error(), etc. are automatically mirrored to your DebugPHP dashboard in real-time.
Register the integration inside your AppServiceProvider.php:
// AppServiceProvider.php — boot()
use DebugPHP\Debug;
public function boot(): void
{
Debug::init(env('SESSION_ID'));
Debug::framework('laravel');
}
Once registered, all Laravel log calls appear on the dashboard automatically:
use Illuminate\Support\Facades\Log;
Log::info('User logged in', ['id' => $user->id]);
Log::warning('Slow query detected');
Log::error('Payment failed', ['order' => $orderId]);
You can customize the integration by passing an options array as the second argument:
Debug::framework('laravel', [
'label' => 'Laravel Logs',
'include_context' => true,
]);
| Option | Type | Default | Description |
|---|---|---|---|
label |
string | 'Laravel' |
Custom label shown on the DebugPHP dashboard for log entries |
include_context |
bool | true |
Whether to include the context array passed to log calls (e.g. ['id' => 1]) |