Documentation

Everything you need to integrate DebugPHP into your project — from installation to self-hosting your own server.

PHP 8.1+ Zero dependencies MIT License
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.

Terminal
composer require callmeleon167/debugphp --dev
Always install as a dev dependency using --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.

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

PHP
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:

PHP
Debug::init('session-token', [
    'enabled' => getenv('APP_DEBUG') === 'true',
]);
Calling 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
Returns 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.

PHP
// 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
Returns self (fluent)

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.

PHP
// 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.

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

All log level methods automatically set the appropriate color and type. You can still override these with method chaining if needed.
Returns Entry|null
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

PHP
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").
Note: The log level methods are shortcuts to 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
Returns static (fluent)

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.

PHP
// 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.

PHP
// 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.

The Auto-clear on new request toggle in the dashboard works on the same 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
stopTimer Returns float ms | 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.

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

PHP
// 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.

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

Sessions expire automatically. The default lifetime is 24 hours, configurable via the 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.

PHP
// 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.

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

Terminal
git clone https://github.com/CallMeLeon167/debugphp-server.git
cd debugphp-server
docker compose up
PHP
Debug::init('your-session-token', [
    'host' => 'http://localhost:8787',
]);
Running inside Docker? Enable auto-detection so the client finds the server automatically:
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.

.env
# 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.
After changing .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:

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:

PHP
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:

PHP
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])