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.
In general, we have the following types of errors:
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.
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
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”.
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