Developer

Avoid these common PHP gotchas

When you are debugging PHP code under a tight deadline, start by looking for the most typical problems. Topping the list are parsing and scope errors.


If you find yourself debugging PHP code at the last minute, it makes sense to look for some of the more common errors first. Here's a rundown of a few likely culprits, such as documents that contain no data and parsing problems—and tips on how to avoid them.

My document contains no data
We’ll start with the hardest problem to debug: the blank page. This mostly happens when you're trying to include or require another page. In plain English, that means you are trying to add content, PHP or otherwise, to be parsed within your script. This is useful for common code such as headers or login forms.

However, if the PHP engine can't find that included page, or the page has errors, it will often cause zero output, making Internet Explorer return some strange HTML, and Netscape/Mozilla fail with the “document contains no data” error.

This happens because many include and require statements end up at the top of the file, and for very good reason: The resources the file contains wouldn’t be very useful if the statements appeared at the end. So we often see no data; nothing has the chance to echo out yet.

Also, because of the way include and require behave—actually processing the files included before actually including them—any error messages can get lost, giving you a false sense of security. The best thing to do is to simply call each include or require in your browser to make sure there are no parse errors.

Another tactic is to exploit the difference in the include and require functions. Although require will produce a fatal error and end script execution, include will simply pass over that point and continue processing the rest of the page. So sometimes it’s worth switching your requires to includes.

If you’re still not sure that the problem is your include or require code, try adding the following:
echo(“got to before require<br>”);
require(“myfile.php”);
echo(“passed require<br>”);

This snippet will display debug messages onscreen that will enable you to determine whether the include code is causing your problems. When you execute it, you’ll know how far the processing engine got.

My variables have become unstuck
According to most PHP proponents, one of the language’s strongest assets is its ability to take any variable with some data attached and make it available to your code. This means you can generate simple dynamic content, such as getting data from the query string, without much hassle. However, security experts warn that this approach could allow people to execute malicious code from within the URL. To combat this, PHP developers turn off register globals for 4.1 onward. If your script relies on them—and many if not most do—be sure to either convert them using the new superglobal arrays or simply turn register globals back on in Php.ini, as shown in the following code:
register_globals = On

The superglobal arrays are simple to use. They consist of seven arrays containing all the information that previously formed individual variables. The most accessed arrays are $_GET[ ], $_POST[ ], $_SESSION[ ] and $_COOKIE[ ]. They contain the query string, form post data, session variables, and cookie variables, respectively.

The remaining arrays are $_SERVER[ ], which contains information about the server; $_ENV[ ], which contains information about the environment; and $_REQUEST[ ]. This array is an amalgamation of the first four arrays. If data is being sent to you, but it could come in multiple ways (for example, both GET and POST), you can use the $_REQUEST[ ] array rather than querying the others, reducing your chances of error.

It’s kinda magic
Another potential troublemaker is PHP's Magic Quotes feature. In fact, Magic Quotes have been so problematic, the feature is disabled by default in new distributions.

The purpose of the Magic Quotes feature is to escape any GET, POST, or COOKIE variable, so the variable is safe for use within databases, among other things, and to reduce the risk of harmful attack. However, it’s a hidden feature, and developers coming from other languages don’t expect it.

When Magic Quotes are unexpected, they can cause variables to be “double quoted,” subsequently breaking database input. The solution, unfortunately, is somewhat tricky, and it depends a lot on how much access you have to your PHP installation. The most sensible thing to do is turn off the feature, because it's most likely interfering with your code. To prevent Magic Quotes from running, simply make sure the following settings in Php.ini are correct:
magic_quotes_gpc = Off
magic_quotes_runtime = Off

Remember, if you have PHP built into the HTTPd binary, or you link dynamically with a shared object, you will need to restart the server to make sure that your changes take effect.

You may also want to take advantage of the get_magic_quotes_runtime() and get_magic_quotes() functions. These will return true or false depending on whether magic_quotes is currently enabled—useful for checking within scripts.

My variables are turning into ghosts
Ever defined a variable and tried to call it within a function, only to have it not work? This is a common problem that is easy to solve. Consider the code in Listing A.

This code won’t work because, as with other languages, PHP variables have scope. This helps keep the namespace free (imagine having to unset temporary variables every time you needed them in functions!) and preserves accidental overwriting. To call a variable from global scope—i.e., any variable assigned outside of a function, into local scope—i.e., a function, you need to use the global keyword, as shown in Listing B.

Now your function will work. In this instance, the following output is produced:

My name is James

My code is correct, but I have parse errors
XML is becoming increasingly important for the Web and for applications, and more people are using it within PHP. For example, one popular technique is to use an XML content parser that also allows some dynamic embedded PHP processing.

In this case, you’ll start the XML document with the same tag as you would PHP, “<?”. The PHP engine will start processing, as it believes the code is PHP, and a parse error will ensue.

Fixing this is simple. Just use either of the following PHP long tags:
<?php … ?>
<script language=”php”> … </script>

The first is generally most friendly. You’ll also need to disable short tags within your Php.ini:
short_open_tag = Off

This will ensure that the parsing engine ignores all XML tags and won’t cause you parsing error pains anymore.

Still having problems? Try the following code, right at the top of your script:
error_reporting(E_ALL);

This may help uncover some more mysterious errors, lurking within your logic.

Being caught out by rogue code is a nightmare, no matter how experienced you are. This article should give you a little extra artillery against the bugs and help reduce your stress level down to a dull roar.

PHP performance
Want to share some PHP performance tips? Drop us an e-mail or post a comment below.

 

Editor's Picks