Debugging

Debugging is the process of fixing problems or errors in your PHP scripts. There are two types of errors, syntax and logic.

Syntax errors

A syntax error occurs when the programmer puts something into a script that the PHP interpreter doesn't recognize. In these cases, PHP simply stops running and by default prints out an error message. The most common types of syntax errors you will commit include:

  • leaving a semicolon off of the end of a statement
  • mismatching single and double quotation marks
  • mismatching parentheses or brackets
  • misspelling a function name
  • passing the wrong number of parameters to a function

When it encounters a syntax error, PHP will stop running (technically, it won't start to run, since your script goes through an "interpretation" stage before you see any output), and prints out an error message that includes the line number on which the error was encoutered. Unfortunately, the line number is not always the one where the error actually exists. However, errors produced by syntax errors are generally helpful, and you can control how these messages are displayed.

The configuration of your instance of PHP depends on what happens when a syntax error occurs. If the configuration setting 'display_errors' in your php.ini file is set to 1 (i.e., TRUE), errors will be printed to the browser. This is a good thing during development but not so good when you move into production, for security reasons we'll look at later. To override this setting in your script, use the following command:

<?php
ini_set
('display_errors', 1); // Determines whether errors are sent to the web browser
?>

To control what is displayed when a syntax error is encountered, use the 'error_reporting()' function, which determines the level (i.e., amount) of information reported in your web server's error log and sent to the browser:

<?php
error_reporting
(0); // no error reporting; set to 0 in production scripts
error_reporting(E_ALL); // report all types of errors
error_reporting(E_NOTICE & E_WARNING); // reports only non-fatal notices (like variables with no values) and warnings (like passing the wrong type of variable to functions)
?>

While developing your scripts, it is useful to use error_reporting(E_ALL).

Logic errors

Logic errors are more difficult to detect and fix, since they stem from problems with your understanding of how the program is working. Your PHP syntax is correct but the way you have implemented your code does not correspond to what you intended to do.

The most common way to track down logic errors is to print out values and compare them to what you think they should be at that point in the script, as we showed at the end of the "PHP and HTML" section. Programmers call this process "inspecting program data".

Inspecting program data is as simple as printing out variable values so you can "inspect" or look at them. Two general strategies for doing this are before/after comparisons and using the print_r() function.

<?php
// Before/after comparisons
$password = 'Okanagan77'; // Before function is applied
$password = str_replace('a', 'X', $password);
print
$password; // After function is applied
?>

<?php
// Using print_r()

$array = array('apples', 'bananas', 'cherries', 'lemons' => 'sour');
print
'<pre>';
print_r($array);
print
'</pre>';

/* Outputs this easy-to-read format:
Array
(
    [0] => apples
    [1] => bananas
    [2] => cherries
    [lemons] => sour
)
*/
?>

Explicitly checking for errors

Some of PHP's built-in functions return TRUE (or some other value that evaluates to true such as an integer other than 0) if they succeed and FALSE (or a value that evaluates to false such as 0) if they don't. You can use this behavior to check for errors and to create user-friendly error messages.

For example, when we write our feedback script, we will be using PHP's mail() function like this:

<?php
$mail_success
= mail($recipient, $subject, $message, $headers);
if (!
$mail_success) {
  print
"Warning: mail to $recipient failed to send using headers $headers ; please consult your system administrator";
?>

mail()'s function documentation says "Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise." If we define a variable that holds mail()'s return value and then test that variable as in this example, we can easily track down why the mail() function failed.

This technique works for user-defined functions as well: their return values can be tested and appropriate messages created depending on the returned value.

Exercises

1. What is the syntax error in the following code?

<?php
$title
= "Debugging for Dummies, ' . $edition . " edition.";
?>

2. Copy this code into your editor and insert print statements to display the values of $question each time it is assigned a value.

<?php
$question
= "What is the meaning of life?";
print
"Question  1 = $question <p />";
$question = strlen($question);

$question = $question / 4;

$question = $question * 2;

$question = "What day of the week is August $question?<p />";

?>

3. Run the following code:

<?php
$amount
= 2;
if (
$amount = 7) {
  print
"OK, amount is $amount";
}
?>

Can you find the bug?

SQL errors

We will not be covering database connectivity during this course, but if you use PHP to write database applications, you will undoubtedly become familiar with SQL errors, which are notoriously useless for debugging purposes.

Advanced debugging

Two topics we won't cover but that you should look into if you are going to do any amount of PHP programming are custom error handlers and debugging development environments.

  • Error handlers are probably too advanced for this class, but you can use functions such as set_error_handler() to define subroutines that contain custom error handling code. An error handler is a function that is called whenever certain types of errors are detected. They are useful because they let you write small amounts of code to handle any type of error, and to do specific things with specific types of errors. For example, you could log PHP warnings to their own log file, replace SQL errors with human-friendly language, or send emails to server admins when certain types of errors occur.
  • Advanced integrated development environments, (known as IDEs) are software products that combine a text editor, code library browsers, debugging tools, performance profilers, and version control systems. IDEs are useful for debugging because they allow you to insert use what are known as "breakpoints", places in your code where you can pause execution and inspect variables, loops, and function calls. Breakpoints allow you to take inspection of program data to the extreme. The leading open source IDE is Eclipse PDT, but commercial products include Komodo, PHPEdit, and the Zend IDE.