Installation Add the bundle to your Laravel project via Composer (note: this is a Symfony2 bundle, but can be adapted for Laravel via Bridge or manually):
composer require cypresslab/di-debugger-bundle
Register the bundle in config/app.php under providers (if using Laravel 5.5+ with auto-discovery, this may not be needed).
First Use Case Run the debug command to inspect your service container:
php artisan di:debug
This will output a structured overview of all registered services, their bindings, and dependencies.
Where to Look First
config/di_debugger.php (if auto-generated) for configuration options.vendor/cypresslab/di-debugger-bundle/README.md for Symfony-specific setup (adapt as needed for Laravel).--format flag to customize output (e.g., --format=json for machine-readable logs).Dependency Inspection Use the bundle to validate service bindings before runtime:
php artisan di:debug --service=App\Services\UserService
This helps identify circular dependencies or missing services early.
Integration with Laravel’s Service Container Manually trigger the debugger in custom commands or middleware:
use Cypresslab\DiDebuggerBundle\Debugger\Debugger;
public function handle()
{
$debugger = new Debugger($this->app->getContainer());
$debugger->debug();
}
Workflow: Debugging a Failed Service
php artisan di:debug --service=FailedService.singleton vs instance).Automated Testing Integrate the debugger into CI pipelines to fail builds on misconfigured services:
php artisan di:debug --fail-on-error
Laravel-Specific Adaptations:
Replace Symfony’s ContainerInterface with Laravel’s Illuminate\Container\Container in the debugger’s constructor.
Example override:
$debugger = new Debugger(app());
Custom Output Formats:
Extend the bundle’s Debugger class to add Laravel-specific formats (e.g., TAP for testing frameworks):
$debugger->setOutputFormat(new LaravelTapFormatter());
Excluding Services:
Use the --exclude flag to ignore third-party services (e.g., vendor/*):
php artisan di:debug --exclude="vendor/laravel/framework"
Symfony vs. Laravel Incompatibilities
ContainerInterface. Laravel’s container extends Illuminate\Container\Container, which may cause:
has() vs bound()).// In a custom Debugger class:
public function has($id)
{
return $this->container->bound($id);
}
Performance Overhead
--service to target specific services or limit scope with --exclude.False Positives
Illuminate\Contracts\Console\Kernel) as "unresolvable" if not explicitly bound.'ignored_services' => [
'Illuminate\Contracts\Console\Kernel',
'Illuminate\Contracts\Http\Kernel',
],
Dynamic Bindings
app()->bindWhen()) may not appear in static output.boot() methods).Verbose Mode:
Use --verbose to see raw container internals, including:
php artisan di:debug --verbose --service=App\Services\*
JSON Output for Scripting:
Pipe output to jq for programmatic analysis:
php artisan di:debug --format=json | jq '.services["App\\Services\\UserService"]'
Extension Points:
Override the Debugger class to add Laravel-specific checks:
class LaravelDebugger extends \Cypresslab\DiDebuggerBundle\Debugger
{
public function checkForLaravelIssues()
{
if (!$this->container->bound('app')) {
throw new \RuntimeException('Laravel container not initialized!');
}
}
}
Missing di_debugger.php:
The bundle may not auto-generate a config file. Manually create it in config/:
return [
'format' => 'text',
'ignored_services' => [],
'fail_on_error' => false,
];
Case Sensitivity: Laravel’s container is case-insensitive for service IDs, but the debugger may not account for this. Normalize IDs in custom implementations:
$id = strtolower($id); // Force lowercase for consistency
How can I help you explore Laravel packages today?