Laravel Debugging with Xdebug
When to Apply
Activate this skill when:
- Debugging application errors or unexpected behavior
- Investigating 500 errors, exceptions, or fatal errors
- Inspecting variables during code execution
- Tracing request flow through routes, controllers, middleware
- Debugging queue jobs, listeners, or workers
- Analyzing Eloquent query performance and N+1 problems
- Testing API endpoints interactively
- Troubleshooting authentication, authorization, or validation issues
- User mentions: debug, breakpoint, step through, Xdebug, inspect variables, dd(), dump()
Prerequisites
Before debugging, ensure:
- Xdebug is installed and configured in PHP
- Xdebug is listening on port 9003 (Xdebug 3.x)
- Laravel project has Xdebug enabled in php.ini
- MCP server is running and connected
Verify Xdebug installation:
Configure Xdebug in php.ini:
ini
xdebug.mode=debug,develop
xdebug.start_with_request=yes
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
Debugging Features
Breakpoint Management
Set breakpoints to pause code execution at specific lines:
Add Breakpoint:
Set breakpoint at DealController.php line 88
Conditional Breakpoint:
Add breakpoint at UserController.php line 45 if $user->id === 1
List Breakpoints:
Show all breakpoints
List active breakpoints
Remove Breakpoint:
Remove breakpoint bp_123abc
Clear all breakpoints
Execution Control
Control code execution flow:
Step Operations:
- Step into - Enter function calls
- Step over - Skip function internals, go to next line
- Step out - Exit current function
- Continue - Run until next breakpoint
Step into the function
Step over to the next line
Step out of this method
Continue execution
Stop debugging
Variable Inspection
Inspect variables at breakpoints:
Local Variables:
Show local variables
Inspect variables in current scope
Get all local variables
Global Variables:
Show global variables
Display superglobals
Evaluate Expression:
Evaluate $user->id
Check if request->has('token')
Run expression: config('app.debug')
Watch Variables:
Watch variable $userData
Add $errors to watch list
dd() Capture & Analysis
Capture and analyze dump output:
Capture the last dump
Show dd() output history
Analyze the most recent dump
Get dump with ID dump_12345
The skill provides:
- Non-blocking dump capture
- Historical dump analysis
- Pattern detection (null values, empty arrays, exceptions)
- Laravel-specific insights (Eloquent models, Collections)
Laravel-Specific Debugging
Debugging Controllers
Workflow:
- Set breakpoint in controller method
- Trigger request via browser, Postman, or curl
- Inspect request data, headers, authenticated user
- Step through query execution
- Check validation errors
- Verify response construction
Example:
Set breakpoint at DealController@store line 88
Trigger POST /api/v1/deals with test data
Show me the request payload
Inspect the $deal variable
Step through validation
Debugging Routes
List Routes:
Run: php artisan route:list
Show routes matching /api/deals
Debug Route Matching:
Why is this route not matching?
Check middleware stack for this route
Debugging Queue Jobs
Launch Configuration:
Use "Laravel Queue Worker" configuration in VS Code
Common Issues:
- Job not processing: Check queue connection and worker status
- Job failing: Set breakpoint in job handle() method
- Memory issues: Inspect large datasets or Eloquent relationships
Debugging Steps:
Start queue worker with Xdebug
Set breakpoint in ProcessDealJob handle()
Dispatch job with test data
Inspect job payload
Step through processing
Debugging Eloquent Queries
Enable Query Log:
php
DB::enableQueryLog();
// Run queries
dd(DB::getQueryLog());
N+1 Query Detection:
Show me the N+1 problem
Analyze Eloquent relationships
Check for eager loading opportunities
Inspect Query Builder:
Evaluate: Deal::where('status', 'active')->toSql()
Show the bindings for this query
Common Debugging Workflows
Debug 500 Error
- Check Laravel logs:
tail -f storage/logs/laravel.log
- Set breakpoint in suspected controller/method
- Trigger the error
- Inspect exception message and stack trace
- Check environment: , database connection
- Step through code to identify root cause
Debug Validation Failure
- Set breakpoint in controller after call
- Inspect object
- Check request data:
- Review validation rules in FormRequest
- Verify expected vs actual data types
Debug Authentication Issues
- Set breakpoint in auth middleware
- Inspect session data
- Check authenticated user:
- Verify token/credentials
- Review guards and providers
Fix N+1 Query Problem
- Enable query logging
- Set breakpoint in controller/relationship method
- Trigger request
- Inspect query log for repeated queries
- Add eager loading:
User::with('posts')->get()
- Verify queries reduced
Troubleshooting
Xdebug Not Connecting
Symptoms: Breakpoints not hit, "connection refused" errors
Solutions:
- Verify Xdebug is installed:
- Check port:
- Verify php.ini configuration
- Restart PHP-FPM or web server
- Check firewall settings
- Ensure Xdebug mode includes "debug"
Breakpoints Not Hitting
Symptoms: Debugger doesn't stop at breakpoints
Solutions:
- Verify file path mappings in VS Code launch.json
- Check breakpoint line numbers match actual code
- Ensure code is actually being executed
- Verify Xdebug is receiving connection: Check
- Try stopping and restarting debugging session
Variable Inspection Not Working
Symptoms: Can't see variable values, empty variables
Solutions:
- Ensure execution is paused at breakpoint
- Check variable scope (local vs global)
- Verify Xdebug max_depth and max_data settings
- Try: instead of locals
- Check for opcache issues: Clear opcache
dd() Blocking Execution
Symptoms: Script terminates at dd(), can't continue
Solutions:
- Use instead of to continue execution
- Use breakpoint instead of dd()
- Check dump capture is enabled
- Verify write permissions in
MCP Server Not Starting
Symptoms: Tools not available, connection errors
Solutions:
- Check PHP version: (requires 8.2+)
- Verify required extensions:
php -m | grep -E "xml|sockets"
- Check server.php is executable
- Review MCP server logs
- Verify .mcp.json configuration
Best Practices
- Use breakpoints instead of dd() - Non-blocking inspection
- Set specific breakpoints - Avoid stopping everywhere
- Use conditional breakpoints - Only stop when condition is true
- Inspect variables at breakpoints - Better than dump statements
- Clear dump history - Prevent disk space issues
- Enable query logging - For database debugging
- Use watch variables - Track specific values across execution
- Review Xdebug logs - for connection issues
Advanced Techniques
Remote Debugging
Debug production or staging environments:
- Configure Xdebug to connect to remote IDE
- Set up SSH tunnel for DBGp connection
- Use appropriate IDE key
- Ensure firewall allows Xdebug port
CLI Debugging
Debug Artisan commands:
php artisan migrate --verbose
Use "Laravel Artisan Command" launch configuration
Test Debugging
Debug Pest tests:
- Set breakpoint in test or application code
- Run specific test:
vendor/bin/pest --filter test_name
- Use "Laravel Tests (Pest)" configuration
Profiling
Use Xdebug profiling for performance analysis:
Analyze cachegrind files with QCacheGrind or similar tools
Quick Reference
| Task | Command |
|---|
| List breakpoints | |
| Add breakpoint | add_breakpoint($file, $line)
|
| Step over | |
| Continue | |
| Get locals | |
| Evaluate | evaluate_expression($expr)
|
| Capture dump | |
Additional Resources
For specific debugging scenarios, see:
references/xdebug-setup.md
- Xdebug installation guide
references/laravel-debugging-patterns.md
- Framework-specific patterns
examples/debugging-controller.md
- Controller debugging examples
examples/debugging-queue-job.md
- Queue debugging examples