Before starting, an understanding of errors will help you quickly recognize where problems exist (and if they are truly problems) in your code, which will lend to faster debugging and understanding where to look for problems.
To start with, we can tell PHP what kind of errors we want to know about before we even run a script. While the full list of supported reporting levels (see Table 8 PHP Errors) covers a variety of concerns, there are a few (notices, errors, and warnings) that cover what we will run into most often.
Notice: Undefined index: message in /home/example.php on line 9
Notices, technically, are not errors. They will notify us of things that we may have intended or wanted, but that PHP can do without. For example, using a variable on a page without declaring it first will generate a notice. PHP will create the variable as soon as it is called, even if we did not declare it, without creating a formal error (other languages would consider this an error worthy of breaking execution). By notifying us but still continuing, if we had already declared or used the variable elsewhere, this notice would indicate a spelling error or mistyped variable name.
Warning: main(): Failed opening 'noFileHere.php' for inclusion on line 2
Warnings still will not stop our script from running but indicate that something has gone wrong during execution of a script. Attempting to use include() on a file that does not exist would create a warning.
PHP Fatal error: Undefined class constant 'MYSQL_ATTR_USE_BUFFERED_QUERY' in database.inc on line 43
Finally, errors are unrecoverable (execution will stop). Typical causes of errors are parsing errors like missing semi-colons, function, or class definitions, or other problems the engine does not know how to resolve. If we used
require() on a file instead of include, an error would be triggered instead.
Most errors that we will receive are parsing errors. They are typically problems caused by what we wrote in our code, like missing brackets, semi-colons, or typos. When we receive an error, the compiler will tell us what problem it discovered and where. Keep in mind that we are being told where an error was found not necessary where the source of the problem exists. For example, a missing semicolon or bracket may have occurred several lines before it created problems for the compiler.
The other category of errors we will run into is logical. These are errors caused by how we wrote our code and can be much more frustrating. Logical errors are usually discovered when the script does not behave as expected. The source can be mistaken in what code we run in different parts of an if/then statement or even an error in the math used in a function that gives us the wrong solution.
Resolving errors can be something of an art form. With parse errors, the engine can guide you to the area to help you begin looking for the source of the error. Logical errors can usually be resolved by adding extra, temporary outputs to follow the value of a variable or trace execution of logic statements through a script. This technique can help you find where what happens differs from what you expect. Unit testing your functions will go a long way toward preventing many of these issues, as does iterative programming.
To dictate what errors we do and do not wish to see in our script output, we will use the
error_reporting() function. By passing one or more of the constants below, we control what is reported. For example, maybe we want information on warnings and errors, but do not care about notices. To do this, we can call
error_reporting(E_WARNING | E_ERROR). The pipe
symbol ( | )works as an or in this case. If we want to see everything except notices we can use
ALLbut leave out notices with the carrot ( ^ ) character to indicate an exception with
error_reporting(E_ALL ^ E_NOTICE). It is good practice to set your error reporting level close to the top of your script, so you can easily find it and change settings:
<?php error_reporting(E_WARNING | E_ERROR); //This next line will trigger a notice that the variable does not exist, but we will not see it echo $test; ?> <?php error_reporting(E_ALL); //This time we will see the notice echo $test; ?>
Notice: Undefined variable: test on line 3
You may be wondering why we would selectively show or hide errors; when we are developing our code, the system errors we will need to see in order to debug are different from what we would want end users to see for a system in production. Revealing, verbatim, the system generated error message is not only confusing to non-programmers but can expose sensitive information to those with malicious intent. Instead, we would provide a message we chose in the error’s place. Take a look at the full list of error reporting levels:
|Fatal run-time errors. These indicate errors that cannot be recovered from, such as a memory allocation problem. Execution of the script is halted.
|Run-time warnings (non-fatal errors). Execution of the script is not halted.
|Compile-time parse errors. Parse errors should only be generated by the parser.
|Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.
|Fatal errors that occur during PHP’s initial startup. This is like an E_ERROR, except it is generated by the core of PHP.
|Warnings (non-fatal errors) that occur during PHP’s initial startup. This is like an E_WARNING, except it is generated by the core of PHP.
|Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine.
|Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine.
|User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function trigger_error().
|User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP function trigger_error().
|User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error().
|Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code.
|Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR.
|Run-time notices. Enable this to receive warnings about code that will not work in future versions.
|User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error().
|All errors and warnings, as supported, except of level E_STRICT prior to PHP 5.4.0.
Table 8 PHP Errors Adapted from php.net, Creative Commons 3.0 Attribution Unported