Skip to content

PHP Tutorial Error Handling

Debugging PHP Applications

Lesson 196 of 369 3 min read By Deepak Paswan Updated Oct 5, 2026

Debugging is finding out why code does not do what you expect. A good method is more useful than any tool.

A simple method

  1. Reproduce the problem with the smallest input you can.
  2. Read the error message and the line number carefully.
  3. Look at the actual values (not the values you think you have).
  4. Change one thing at a time.
  5. Confirm the fix, and think about why the bug happened.

Look at values: var_dump() and print_r()

index.php
PHP
<?php
$user = ["name" => "Ana", "age" => "29", "tags" => []];

var_dump($user["age"]);
print_r($user);
Output
OUTPUT
string(2) "29"
Array
(
    [name] => Ana
    [age] => 29
    [tags] => Array
        (
        )

)

var_dump() shows the type (string(2) "29", a string, not a number). That detail solves many bugs.

Make debug output readable in a browser

In HTML, whitespace collapses. Wrap the output in <pre>.

index.php
PHP
<?php
echo "<pre>";
var_dump($data);
echo "</pre>";

Log instead of printing

On a live site (or when printing would break the page, such as in JSON or a redirect), write to the log.

index.php
PHP
<?php
error_log("order total: " . var_export($total, true));
error_log(print_r($order, true));

var_export($x, true) and print_r($x, true) return a string instead of printing.

Read the stack trace

index.php
PHP
<?php
function a(): void { b(); }
function b(): void { c(); }
function c(): void { throw new RuntimeException("deep problem"); }

try {
    a();
} catch (RuntimeException $e) {
    foreach ($e->getTrace() as $i => $frame) {
        echo "#$i " . $frame["function"] . "()\n";
    }
}
Output
OUTPUT
#0 c()
#1 b()
#2 a()

The trace lists the calls from the point of failure back to where it started. Start at the top: that is where the exception was created.

Assertions with clear messages

Check your assumptions early.

index.php
PHP
<?php
function average(array $numbers): float
{
    if ($numbers === []) {
        throw new InvalidArgumentException("average() needs at least one number");
    }

    return array_sum($numbers) / count($numbers);
}

try {
    average([]);
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
}
Output
OUTPUT
average() needs at least one number

Bisect: cut the problem in half

If a long script fails somewhere, add echo "reached here\n"; exit; in the middle. If you see the message, the bug is below it. Move the line and repeat. You find the line in a few steps.

Xdebug: a real debugger

Xdebug is a PHP extension that lets you:

  • Pause the program at a breakpoint.
  • Step through the code line by line.
  • Inspect every variable.
  • See the call stack.

You install it, and connect your editor (VS Code with a PHP debug extension, or PhpStorm). Then you click in the margin to set a breakpoint and load the page. Setup steps depend on your system, so follow the guide at xdebug.org.

Other helpful tools

  • Browser Network tab: see the real response, status code and headers.
  • php -l file.php: check syntax without running the file.
  • Static analysers such as PHPStan and Psalm find bugs without running the code.
  • Tests with PHPUnit or Pest keep a bug from returning.

Do not debug on the live site

Turn on error display only on your own machine. If you must debug production, use logs and a debugger on a copy, not display_errors on a public page.

lightbulb
Rubber duck debugging
Explain the code, line by line, out loud to an object (or a patient colleague). Many bugs reveal themselves when you describe what each line should do.

Exercise: find the bug

This function should return the average, but it prints the wrong result for ["10", "20"]. Use var_dump() mentally. What is the problem?

index.php
PHP
<?php
function average(array $numbers) {
    $sum = "";
    foreach ($numbers as $n) { $sum .= $n; }
    return $sum / count($numbers);
}
Show the answer

$sum starts as an empty string, and .= joins the values (“1020”). The result is 1020 / 2 = 510. The fix is $sum = 0; and $sum += $n;, or simply array_sum($numbers).