Web Database Applications with PHP \& MySQLWeb Database Applications with PHP \& MySQLSearch this book

2.12. Common Mistakes

When switching to PHP, there are several common mistakes even experienced programmers make. In this short section, we highlight some of these mistakes and the basics of how to rectify them.

2.12.1. A Page That Produces Partial or No Output

One of the most common problems in debugging PHP scripts is seeing:

Most of these problems are caused not by a bug in script-programming logic, but by a bug in the HTML produced by the script. For example, if the </table>, </form>, or </frame> closing tags are omitted, the page may not be rendered.

The HTML problem can usually be identified by viewing the HTML page source using the web browser. With Netscape, the complete output of the erroneous example is shown in the page-source view, and the HTML problem can hopefully be easily identified.

For compound or hard-to-identify HTML bugs, the W3C validator at http://validator.w3.org retrieves a page, analyzes the correctness of the HTML, and issues a report. It's an excellent assistant for debugging and last-minute compliance checks before delivery of an application.

If the problem still proves hard to find, consider adding calls to the flush( ) function after echo, print, or printf statements. flush( ) empties the output buffer maintained by the PHP engine, sending all currently buffered output to the web server. The function has no effect on buffering at the web server or the web browser, but it ensures that all data output by the script is available to the web server to be transmitted and rendered by a browser. Remember to remove the flush( ) function calls after debugging, because unnecessary flushing may prevent efficient buffering of output by the PHP scripting engine.

A common problem that shouldn't be confused with those described here is not receiving a response from the web server and getting a "no response" error message. This problem is a symptom of the bugs described in the next section, and can be distinguished from the problems described here by observing the web browser. Most of the popular graphical browsers show they are waiting for a response by animating the logo in the top-right corner. For the HTML problems described here, the page loading process will be complete, the logo animation will have stopped, and the HTML page source can be viewed through the web browser menus.

2.12.2. Variable Problems

In this section, we discuss problems that cause a page never to arrive at the web browser, or complete pages to appear with missing output from variables.

2.12.2.1. Variable naming

Making a mistake with a variable name sometimes inadvertently creates never-ending loops. The result of a never-ending loop is that the web browser eventually times out and alerts the user that the web server isn't responding to an HTTP request.

The following loop never ends, and no output is produced:

for($counter=0; $counter<10; $Counter++)
  myFunction( );

The variable $counter is never incremented. Instead, another variable, $Counter, is, so $counter is always less than 10. Common bugs result from subtle changes in variable names through changing case, omitting or including underscores, or simple typographic errors.

Never-ending loops can also produce unexpected output. The following loop can render thousands of greetings in a web browser in a very short time:

for($counter=0; $Counter<10; $counter++)
  echo "<br>hello";

These errors can sometimes be detected by setting the PHP error-reporting level to a higher sensitivity. Adding the following code fragment to the top of each PHP script or to a file included with the require directive reports undefined variable errors:

error_reporting(E_ALL);

This forces variables to be declared by assigning a value before they can be used. Consider the following example:

error_reporting(E_ALL);
for($counter=0; $Counter<10; $counter++)
  echo "<br>hello";

This produces an unending number of warning messages stating:

Warning: Undefined variable: Counter in /var/lib/apache/htdocs/winestore/a.php on line 2

The script keeps on running, because it's only a warning. A custom error handler can be incorporated that stops the script when an error or warning is encountered by using the set_error_handler( ) function. We discuss error handlers in Chapter 10.

2.12.2.2. Missing output

An uninitialized variable produces no output. This seems obvious, but it can be hard to identify if the problem is a subtle typographic error. Consider this example of a change in case:

$testvariable = "hello";
echo "The value of test is $testVariable";

This produces the string:

The value of test is 

The problem can be much harder to identify by visual inspection if the variable is part of a complex operation, such as being used as an array element index, part of <table> output, or as a parameter to a database query.

If output appears but isn't as expected, an uninitialized variable is a possibility. The simplest approach to detecting the error is then to check for a bug by setting error_reporting(E_ALL) at the top of the script as discussed in the last section.

The function isset( ) can also control execution and debug code, because it returns true if the variable exists (even if it's set to NULL or an empty string) and false if it has never been used.

Another related problem involves variable names appearing where values should. This is usually the simple problem of an omitted dollar sign and is easy to fix. For example:

echo "the value of test is test";

This should have been:

echo "the value of test is $test";

If a dollar sign is omitted in a statement such as an assignment or conditional, the PHP interpreter reports a specific parse error with its default error-reporting level.

A similar problem can also occur when single quotes are used instead of double quotes, because single-quoted strings are always output directly, and the string isn't interpreted like a double-quoted string is. For example:

echo 'the value of test is $test';

This produces:

the value of test is $test

It doesn't output the value of the variable $test.

2.12.3. Complaints About Headers

We have not introduced the functions header( ) and setcookie( ) in this chapter. Both functions can output HTTP headers that are sent by the web server back to the web browser, and they are used frequently in web database applications. The functions are introduced and discussed in Chapter 5, Chapter 6, Chapter 8, and Chapter 9.

A common problem seen in producing HTTP headers with PHP is the error message beginning:

Warning: Cannot add header information - headers already sent...

Headers can be sent only before any HTML is output, and this includes any whitespace at the top of the file. So, for example, if there is a blank line or single space character before the script open tag <?php, HTML has been output—albeit not very interesting HTML—and the call to header( ) or setcookie( ) reports this error.

It's possible to avoid header problems by altering how PHP buffers data using the output control library functions. These functions are outside the scope of this book.

2.12.4. Other Common Problems

The three problem categories we have outlined so far are the most infuriating and common mistakes programmers make in PHP. We outline a few less common and less PHP-specific problems here.

Omitting a semicolon at the end of a statement is usually easy to detect. The PHP interpreter continues to parse the script and, when it reaches a threshold of confusion or exceeds the maximum statement length, it reports an error one or more lines later that indicates a semicolon has been missed. In most cases, this is easy to fix, and the line missing the semicolon is identified in the error message.

In some cases, a missing semicolon can be as hard to identify as a missing closing brace or a missing quotation mark. The following erroneous code is missing a closing brace:

<?
for($x=0; $x<100 ;$x++)
{
  for($y=0; $y<100; $y++) {
    echo "test1";
    for($z=0; $z<100; $z++)
      echo "test2";
}     
?>

The error reported is:

Parse error: parse error in bug.php on line 9

Line 9 is the last line of the script, so the nature and cause of the problem aren't immediately clear. However, parse errors that aren't immediately obvious on the reported line in the error message are usually on the line above, or there may be a missing brace or quotation mark.

It takes only a minute or so to identify the missing brace in this example, but more complex functions can take much longer to fix. This highlights the importance of indentation in code and also of avoiding the practice of placing opening braces at the ends of lines. Braces should always be placed on lines of their own.

Missing open and close script tags can cause similar problems, but these are much easier to identify. If an open script tag is missing, it's obvious because some portion of the code—if not all—is displayed in the browser. A missing close tag usually causes a parse error, because the PHP script engine is confused when it tries to parse HTML and interpret it as PHP.

If script source is always displayed and never run, it's likely that Apache is misconfigured. Specifically, it's likely that the AddType directive for processing PHP scripts was not uncommented in the Apache installation process; this seems to be the default in recent RedHat Linux distributions.

Another possible cause of scripts being displayed and not run is that the PHP scripts aren't saved in files ending with the .php suffix. This problem often occurs with legacy PHP3 code, because PHP3 scripts usually use the .php3 suffix. The problem can be corrected by renaming the script files so they end in the .php suffix or by adding an additional AddType directive to the Apache httpd.conf file:

AddType application/x-httpd-php .php3

In some rare cases, a PHP3 script might require minor modifications to run under PHP4.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.