buggregator/trap
Buggregator Trap enhances PHP debugging with instant Symfony VarDumper integrations, handy helper functions, and a lightweight local Buggregator server (no Docker). Connect to any Buggregator server and pair with the PhpStorm plugin for a smooth workflow.
Installation:
composer require --dev buggregator/trap -W
Ensure it's added to require-dev in composer.json.
Start the Server:
vendor/bin/trap
The server starts on default ports (9912, 9913, 1025, 8000) and displays dumps in the console by default.
First Debug Use Case:
Replace dump() with trap() in your Laravel code:
use Buggregator\Trap\Trap;
// Basic usage
trap($user); // Sends dump to local server
// With options
trap($query)->depth(2)->times(5);
php artisan tinker and test trap() with a complex object (e.g., Eloquent model or request).vendor/bin/trap is running.vendor/bin/trap -p9912 --ui=8080
public function show(Request $request, User $user)
{
// Dump request + user with depth limit
trap($request->all(), user: $user)->depth(3);
// Conditional dump (e.g., only for admins)
if ($request->user()->isAdmin()) {
trap($user->roles)->once()->if($user->isAdmin());
}
}
Configure Monolog to use Trap as a handler in config/logging.php:
'channels' => [
'trap' => [
'driver' => 'monolog',
'handler' => Buggregator\Trap\Handler\MonologHandler::class,
'with' => ['port' => env('TRAP_TCP_PORTS', '9912')],
],
],
Then log as usual:
Log::channel('trap')->info('User action', ['user_id' => $user->id]);
Create middleware to trap incoming requests:
namespace App\Http\Middleware;
use Buggregator\Trap\Trap;
use Closure;
class TrapRequests
{
public function handle($request, Closure $next)
{
trap($request->all(), headers: $request->header())->depth(2);
return $next($request);
}
}
Register in app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\TrapRequests::class,
];
Use the mail-to-file sender to capture emails:
vendor/bin/trap -smail-to-file
Emails are saved in runtime/mail/{recipient} as JSON files.
Use tr() (trace + return) for timing critical sections:
$result = $this->processor->process(tr(data: $data));
Service Container Binding: Bind Trap to the container for dependency injection:
$this->app->singleton(Trap::class, function () {
return new Trap(['sender' => 'server', 'host' => 'localhost']);
});
Then inject Trap into controllers/services.
Artisan Commands: Use Trap in custom Artisan commands for debugging:
use Buggregator\Trap\Trap;
class DebugCommand extends Command
{
protected $signature = 'debug:model {model}';
protected $description = 'Debug a model instance';
public function handle()
{
$model = app($this->argument('model'));
trap($model)->depth(5);
}
}
Exception Handling:
Override App\Exceptions\Handler to trap exceptions:
public function report(Throwable $exception)
{
trap($exception)->depth(3);
parent::report($exception);
}
Port Conflicts:
9912, 9913, 1025, and 8000. If another service (e.g., Laravel Valet, Docker) uses these, dumps may fail silently.vendor/bin/trap -p9914 --ui=8081
Or in .env:
TRAP_TCP_PORTS=9914,9915,1026,8081
Missing Dumps:
vendor/bin/trap).$_SERVER['REMOTE_ADDR'] isn’t overridden (Trap auto-sets it if missing).Protobuf Dump Formatting:
google/protobuf dumps. If not working, ensure the package is loaded before trap() calls.Phar vs. Composer:
trap.phar) may not pick up project-specific configs.Memory Leaks:
depth() and times() limits:
trap($largeArray)->depth(2)->times(100);
CLI Debugging:
Use td() (trace + die) to halt execution and inspect state:
if ($user->isAdmin()) {
td($user->permissions); // Exit after dump
}
Remote Server Integration: To send dumps to a remote Buggregator server (e.g., for staging/prod):
vendor/bin/trap -sserver -hbuggregator.example.com
Conditional Dumps:
Use if() to avoid dumping in production:
trap($sensitiveData)->if(app()->environment('local'));
Custom Senders:
Extend Trap’s Sender interface to create a database sender:
use Buggregator\Trap\Sender;
class DatabaseSender implements Sender
{
public function send(array $data): void
{
DB::table('debug_dumps')->insert($data);
}
}
Register it via:
vendor/bin/trap -scustom
Environment Variables:
TRAP_TCP_HOST: Override the default 127.0.0.1 (e.g., for Docker: host.docker.internal).TRAP_UI_PORT: Change the web UI port (default: 8000).Symfony VarDumper: Trap enhances VarDumper globally. To revert to default behavior, exclude Trap’s autoloader or use:
use Symfony\Component\VarDumper\Cloner\VarCloner;
$cloner = new VarCloner(); // Bypasses Trap's enhancements
Phar Limitations: The Phar version lacks project-specific configs (e.g., custom senders). Use the Composer version for full features.
Custom Handlers:
Extend Buggregator\Trap\Handler\HandlerInterface to create a Slack handler:
class SlackHandler implements HandlerInterface
{
public function handle(array $data): void
{
$webhook = config('services.slack.webhook');
Http::post($webhook, ['json' => $data]);
}
}
Register via CLI:
vendor/bin/trap -scustom -hSlackHandler
Protocol-Specific Traps:
Use trap()->protocol('http') to force HTTP dumps (e.g., for API debugging):
trap($request->json())->protocol('http');
Asset Uploads:
Trap supports uploading files (e.g., images from Storage). Use the asset sender:
How can I help you explore Laravel packages today?