Previous Section  < Day Day Up >  Next Section

12.2 Fixing Parse Errors

The PHP interpreter is really picky but not very chatty. If you leave out a necessary semicolon, or start a string with a single quote but end it with a double quote, the interpreter doesn't run your program. It throws up its (virtual) hands, complains about a "parse error," and leaves you stuck in the debugging wilderness.

This can be one of the most frustrating things about programming when you're getting started. Everything has to be phrased and punctuated just so in order for the PHP interpreter to accept it. One thing that helps this process along is writing your programs in an editor that is PHP-aware. This is a program that, when you tell it you are editing a PHP program, turns on some special features that make programming easier.

One of these special features is syntax highlighting. It changes the color of different parts of your program based on what those parts are. For example, strings are pink, keywords such as if and while are blue, comments are grey, and variables are black. Syntax highlighting makes it easier to detect things such as a string that's missing its closing quote: the pink text continues past the line that the string is on, all the way to the end of the file (or the next quote that appears later in the program).

Another feature is quote and bracket matching, which helps to make sure that your quotes and brackets are balanced. When you type a closing delimiter such as }, the editor highlights the opening { that it matches. Different editors do this in different ways, but typical methods are to flash the cursor at the location of the opening {, or to bold the { } pair for a short time. This behavior is helpful for pairs of punctuation that go together: single and double quotes that delimit strings, parentheses, square brackets, and curly braces.

These editors also show the line numbers of your program files. When you get an error message from the PHP interpreter complaining about a parse error in line 35 in your program, you can focus on the right place to look for your error.

Table 12-1 lists seven PHP-aware editors. Some of them go beyond the basics of syntax highlighting and bracket matching and provide more advanced features to help your coding. These features are listed in the "Comments" column of the table.

Table 12-1. PHP-aware text editors

Name

Platform(s)

URL

Cost

Comments

BBEdit

OS X

http://www.barebones.com/products/bbedit/index.shtml

$179

 

Emacs and XEmacs

All

http://www.gnu.org/software/emacs/, http://www.xemacs.org

Free

 

Komodo

Windows, Linux, Solaris

http://www.activestate.com/Products/Komodo/

$29.95 (personal), $295 (professional

Provides context-sensitive PHP function and class lookup and completion; includes integrated debugger.

Macromedia Dreamweaver MX 2004

Windows, OS X

http://www.macromedia.com/software/dreamweaver/

$399

 

NuSphere PHPEd

Windows, Linux

http://www.nusphere.com/products/index.htm

$299

Provides context-sensitive PHP function and class lookup and completion; includes profiler and debugger.

PHPEdit

Windows

http://www.phpedit.net/products/PHPEdit/

Free

Provides context-sensitive PHP function and class lookup and completion; includes the DBG PHP debugger.

Zend IDE

Windows, Linux, OS X

http://www.zend.com/store/products/zend-studio.php

$195

Provides context-sensitive PHP function and class lookup and completion; highlights syntax errors in real time; includes profiler for speed-testing code and integrated debugger.


Parse errors happen when the PHP interpreter comes upon something unexpected in your program. Consider the broken program in Example 12-1.

Example 12-1. A parse error
<?php

if $logged_in) {

        print "Welcome, user.";

    }

?>

When told to run the code in Example 12-1, the PHP interpreter produces the following error message:[1]

[1] Shown is the error message that PHP 5 produces. PHP 4 prints parse errors slightly differently.

Parse error: parse error, unexpected T_VARIABLE, expecting '(' in welcome.php on line 2

That error message means that in line 2 of the file, the PHP interpreter was expecting to see an open parenthesis but instead it encountered something called T_VARIABLE. The T_VARIABLE is called a token. It's the PHP interpreter's way of expressing different fundamental parts of programs. When the interpreter reads in a program, it translates what you've written into a list of tokens. Wherever you put a variable in your program, there is a T_VARIABLE token in the interpreter's list.

So what the PHP interpreter is trying to tell you with the error message is "I was reading line 2 and saw a variable where I was expecting an open parenthesis." Looking at line 2 of Example 12-1, you can see why this is so: the open parenthesis that should start the if( ) test expression is missing. After seeing if, PHP expects a ( to start the test expression. Since that's not there, it sees $logged_in, a variable, instead.

A list of all the tokens that the PHP interpreter uses (and therefore that may show up in an error message) is in the PHP online manual at http://www.php.net/tokens.

The insidious thing about parse errors, though, is that the line number in the error message is often not the line where the error actually is. Example 12-2 has such an error in it.

Example 12-2. A trickier parse error
<?php

$first_name = "David';

if ($logged_in) {

    print "Welcome, $first_name";

} else {

    print "Howdy, Stranger.";

}

?>

When it tries to run the code in Example 12-2, the PHP interpreter says:

Parse error: parse error, unexpected T_STRING in welcome.php on line 4

That error makes it seem like line 4 contains a string in a place where it shouldn't. But you can scrutinize line 4 all you want to find a problem with it, and you just won't find one. That line, print "Welcome, $first_name"; is perfectly correct梩he string is correctly delimited with double quotes and the line appropriately ends with a semicolon.

The real problem in Example 12-2 is in line 2. The string being assigned to $first_name starts with a double quote but "ends" with a single quote. As the PHP interpreter reads line 2, it sees the double quote and thinks "OK, here comes a string. I'll read everything until the next (unescaped) double quote as the contents of this string." That makes the interpreter fly right over the single quote in line 2 and keep going all the way until the first double quote in line 4. When it sees that double quote, the interpreter thinks it's found the end of the string. So then it considers what happens after the double quote to be a new command or statement. But what's after the double quote is Welcome, $first_name";. This doesn't make any sense to the interpreter. It's expecting an immediate semicolon to end a statement, or maybe a period to concatenate the just-defined string with another string. But Welcome, $first_name"; is just an undelimited string sitting where it doesn't belong. So the interpreter gives up and shouts out a parse error.

Imagine you're running down the streets of Manhattan at supersonic speed. The sidewalk on 35th Street has some cracks in it, so you trip. But you're going so fast that you land on 39th Street and dirty the pavement with your blood and guts. Then a traffic safety officer comes over and says, "Hey! There's a problem with 39th Street! Someone's soiled the sidewalk with their innards!"

That's what the PHP interpreter is doing in this case. The line number in the parse error is where the interpreter sees something it doesn't expect, which is not always the line number where the actual error is.

When you get a parse error from the interpreter, first take a look at the line reported in the parse error. Check for the basics, such as making sure that you've got a semicolon at the end of the statement. If the line seems OK, work your way forward and back a few lines in the program to hunt down the actual error. Pay special attention to punctuation that goes in pairs: single or double quotes that delimit strings, parentheses in function calls or test expressions, square brackets in array elements, and curly braces in code blocks. Count that the number of opening punctuation marks (such as (, [, and {) matches the number of closing punctuation marks (such as ), ], and }).

    Previous Section  < Day Day Up >  Next Section