code quality and tooling
phpdbg Basics
phpdbg is PHP's command-line debugger SAPI. It lets you run PHP scripts under a debugger, set breakpoints, step through execution, and inspect values without installing a browser extension or configuring an IDE.
You will see Xdebug more often in day-to-day web debugging, but phpdbg is still useful for CLI scripts, learning how debuggers work, and some testing/coverage workflows.
Check whether phpdbg is available
phpdbg is a separate executable. It may already be installed with PHP, or it may need an extra package depending on your operating system.
phpdbg -v
If the command is not found, the lesson still matters conceptually, but the local machine needs the phpdbg package before you can practise interactively.
Use a small script
Debuggers are easiest to learn with a tiny script.
<?php
declare(strict_types=1);
function discountForSubtotal(int $subtotal): int
{
if ($subtotal >= 5000) {
return 500;
}
return 0;
}
$subtotal = 5000;
$discount = discountForSubtotal($subtotal);
echo $discount . PHP_EOL;
// Prints:
// 500
Save this as discount.php.
Start phpdbg
You can start an interactive debugger session for the script.
phpdbg -q discount.php
The -q option starts phpdbg quietly, without the longer welcome text. Once inside the prompt, you can set breakpoints and run the script.
Set a breakpoint
A breakpoint pauses execution at a chosen place. You can break on a file and line.
break discount.php:15
run
When execution reaches that line, phpdbg pauses. This lets you inspect values before the script continues.
You can also break when a function is entered.
break discountForSubtotal
run
Breaking on a function is useful when you know which function is suspicious but do not want to count line numbers.
Inspect a value
At the phpdbg prompt, evaluate a variable with ev.
ev $subtotal
If execution has paused after $subtotal has been assigned, phpdbg can show its current value.
Inspecting the value at a breakpoint is often cleaner than adding temporary var_dump() calls to the code.
Step through execution
Stepping runs the script a small amount at a time. In a debugger, that lets you watch how values change as each line runs.
step
ev $discount
The exact amount of movement can feel low-level in phpdbg because it is close to PHP's execution engine. For beginner work, use stepping sparingly and prefer well-placed breakpoints.
Continue or quit
After inspecting the state, continue execution or leave the debugger.
continue
quit
The important workflow is:
- start phpdbg
- set a breakpoint
- run the script
- inspect variables
- step or continue
- quit when finished
When phpdbg helps
phpdbg is useful when:
- a CLI script behaves differently from what you expect
- you want to pause inside a function without editing the file
- repeated
var_dump()calls are making the script noisy - you want to understand how a small script flows
- a project uses phpdbg for test coverage or CI tooling
For full web request debugging, Xdebug with an IDE is usually more ergonomic. That comes later.
What to remember
phpdbg is a terminal debugger for PHP. It is not a replacement for understanding the code, but it gives you a way to pause execution and inspect values at the exact point where a bug is happening.
Before moving on, make sure you can explain what a breakpoint is, why inspecting a variable at runtime is useful, and why a debugger can be cleaner than leaving temporary output in the code.
Practice
Task: Inspect A Value With phpdbg
Write the phpdbg command sequence you would use to inspect $subtotal inside this script.
<?php
declare(strict_types=1);
function discountForSubtotal(int $subtotal): int
{
if ($subtotal >= 5000) {
return 500;
}
return 0;
}
$subtotal = 5000;
$discount = discountForSubtotal($subtotal);
echo $discount . PHP_EOL;
Assume the file is named discount.php.
Requirements
- Start phpdbg quietly.
- Set a breakpoint in
discountForSubtotal(). - Run the script.
- Evaluate
$subtotal. - Quit the debugger.
Show solution
phpdbg -q discount.php
At the phpdbg prompt:
break discountForSubtotal
run
ev $subtotal
quit
The breakpoint pauses execution when discountForSubtotal() is entered. At that point, evaluating $subtotal should show the value passed into the function.