Ioannis Bekiaris

All You Need to Know About Error Reporting in PHP

There is a lot of discussion about PHP errors. According to Google, a lot of people are looking for a concise and clear answer to questions such as “What are the types of PHP errors?” or “How do I stop displaying errors?”. In short, what developers are looking for, is error reporting in PHP.

What are the types of errors in PHP?

In general, we have the following types of errors:

  • Fatal errors
  • Parse errors
  • Warnings
  • Notices

Those can be runtime and/or compile-time errors.

Runtime and compile-time, are programming terms that refer to different stages of a software application. Compile-time is the instance where the code you entered is converted to executable while run-time is the instance where the executable is running.

In essence, if your PHP script fails during execution, then it’s a run-time error; if it fails before, we are talking about compile-time one.

For example, syntax errors or a Zend Engine ones, are compile-time errors in PHP.

There are some fatal errors that could occur during PHP’s initial startup. We usually call those CORE errors as they are generated by the core of PHP. For example, safe mode is removed from PHP (since PHP 5.4.0) and generates a CORE error when enabled.

What is the difference between an Error (Fatal Error), a Warning and a Notice?

In the context of this question, we’re discussing about run-time errors. A Fatal Error is a failure that we cannot recover from. For example, we cannot recover from exhaustion of memory or a call to an undefined method. In those cases, the script is halted. On the other hand, Warnings and/or Notices are kind of non-fatal errors as they don’t halt the execution of the script.

Let’s see some examples in PHP:

<?php declare(strict_types=1);

$bar = 1;

// Notice: Undefined variable: foo
echo $foo;

// PHP Warning:  include(bar.php): failed to open stream: No such file or directory
include 'bar.php';

// PHP Fatal error:  Uncaught Error: Call to undefined function testMethod()
echo testMethod();

// PHP Parse error:  syntax error
$test = 1

Throw or trigger errors?

Reading from the official PHP documentation:

PHP 7 changes how most errors are reported by PHP. Instead of reporting errors through the traditional error reporting mechanism used by PHP 5, most errors are now reported by throwing Error exceptions.

In PHP 7, Error is the base class for all internal PHP errors. It implements Throwable interface. In the previous versions of PHP, we were discussing about triggered errors. Back then, errors weren’t Throwables.

We still can trigger an error in the old fashioned way, by using the trigger_error method. In the following example (in PHP7) you can see the difference:

<?php declare(strict_types=1);

try {
    trigger_error('This is a PHP ERROR', E_USER_ERROR);
    echo testMethod();
} catch (\Throwable $e) {
    // Do nothing   
}

echo I am running on PHP7;


The error that is triggered via the “old” mechanism isn’t a Throwable and as a result, the execution of the script will stop on that line, with the following error message:

PHP Fatal error:  This is a PHP ERROR
Fatal error: This is a PHP ERROR

If you comment out the trigger_error:

<?php declare(strict_types=1);

try {
    // trigger_error('This is a PHP ERROR', E_USER_ERROR);
    echo testMethod();
} catch (\Throwable $e) {
    // Do nothing   
}

echo 'I am running on PHP7';

the script will be executed as normally and the thrown Error is caught in the try-catch block.

NOTE: Warnings and Notices are not Throwables. That means that a Warning or a Notice cannot be caught in a try-catch block.

But why PHP prints the error message twice?

If you run the previous example from the CLI and without any specific php.ini configuration, you’ll see that the error message is printed twice. Why does it happen?

Did you ever heard about streams?

Reading from Wikipedia:

In computer programming, standard streams are preconnected input and output communication channels between a computer program and its environment when it begins execution. The three input/output (I/O) connections are called standard input (stdin), standard output (stdout) and standard error (stderr)… Standard error is another output stream typically used by programs to output error messages or diagnostics.

So, the first error message is coming from the STDERR, while the second one is coming from the STDOUT stream. In a CLI application, STDERR stream is used by default to log errors and, in general, STDOUT is used to send errors to the output “device”.

Report and/or display errors

PHP gives you all that you need in order to select IF and WHAT TYPE of errors you would like to log and/or display. You can always change your php.ini configuration file or you can override your php.ini settings by setting directives at runtime.

In the previous example, you can select to log the error and not display it, by using the setting the following directives in your script:

<?php declare(strict_types=1);

ini_set('log_errors', 1);
ini_set('display_errors', 0);

display_errors determines whether errors should be printed to the screen as part of the output while log_errors tells whether script errors should be logged.

You can always define the error levels that you want to display and/or log.

For that purpose, you should use the error_reporting() function which sets the error_reporting directive at runtime. Alternatively, you can set error_reporting directive in your php.ini file. error_reporting() function accepts PHP levels combined with bitwise operators.

For example:

<?php

// Turn off all error reporting
error_reporting(0);

// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Report all PHP errors
error_reporting(-1);

// Same as error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);

Last but not least, remember that you can select where to log your errors by setting error_log directive at runtime or in your php.ini configuration. For example, you can select a file or send errors to the SAPI error logger by default. Error logger is an error log in Apache or STDERR in CLI environment.

Read more about PHP error levels in the following link: https://www.php.net/manual/en/errorfunc.constants.php