Section 3: Scripting Languages
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 ) 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 semi colon or bracket may have occurred several lines before it created a problems for the compiler.
The other category of errors we will run into are 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 mistakes in what code we run in different parts of an if/then statement or even an error in 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 E_ALL but 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:
- 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;
- //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:
Table 8 PHP Errors