Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Errors and debugging

Besides the exceptions your code throws, PHP itself reports problems: reading a variable that does not exist, dividing by zero, a typo in a function name. Being able to read these messages saves hours of bug hunting.

Kinds of messages

KindWhat it meansThe program continues
Notice, DeprecatedA remark: a possible inaccuracy, an outdated featureYes
WarningSomething went wrongYes
Fatal errorA fatal errorNo
Parse errorA syntax error in the codeIt does not start

A warning does not stop the program, but it almost always means a logic error. It must not be ignored.

Reading a message

A message names the cause, the file and the line number:

Warning: Undefined variable $total in /var/www/cart.php on line 12

Start with the line given. If it looks fine, look above it: the cause is often a few lines earlier.

Displaying errors

During development errors are shown on screen; on a live site they are written to a log. Settings control this:

<?php
 
error_reporting(E_ALL);
ini_set('display_errors', '1');
 
echo 'All errors are shown';

On a production server display_errors is turned off: an error message reveals file paths and code details to the visitor.

The error log

The error_log() function writes a message to the server log. The user does not see it:

<?php
 
function divide(int $a, int $b): ?float
{
    if ($b === 0) {
        error_log('Attempt to divide by zero');
 
        return null;
    }
 
    return $a / $b;
}
 
echo divide(10, 4); // 2.5

Warnings as exceptions

A warning cannot be caught with try. The set_error_handler() function lets you turn it into an exception — and handle every problem in one way:

<?php
 
set_error_handler(function (int $level, string $message) {
    throw new ErrorException($message);
});
 
try {
    echo $undefined;
} catch (ErrorException $error) {
    echo 'Caught: ', $error->getMessage();
}

Frameworks do exactly this: any notice stops execution and ends up in the common handler.

Debugging

To see what a variable holds, print it with var_dump() — it shows both the type and the value:

<?php
 
$user = ['name' => 'Anna', 'age' => 25, 'active' => true];
 
var_dump($user['age']);
echo json_encode($user);

For large arrays print_r() or json_encode() is handier. Serious projects use the Xdebug debugger: it stops the program at a chosen line and shows every variable.

A global exception handler

set_exception_handler() sets a function that receives any uncaught exception. It shows the visitor a polite page and writes the details to the log:

<?php
 
set_exception_handler(function (Throwable $error) {
    echo 'Something went wrong. We are already looking into it.';
});
 
throw new RuntimeException('The database is unavailable');

Common mistake

The @ operator before an expression suppresses the error message. The problem does not go away — you just stop seeing it:

<?php
 
$config = ['theme' => 'dark'];
 
// Bad: $size = @$config['size'];
 
$size = $config['size'] ?? 14;
 
echo $size; // 14

Instead of suppressing, check the data: the ?? operator, isset(), file_exists().

Thanks for reading!

Donate to the site — we work hard for you.