Debugging Techniques

Chapter 11 - Debugging Your Code
byGareth Downes-Powellet al.
Wrox Press 2003

In this section we're going to look at techniques to make debugging quicker and easier, and we demonstrate some functions you can use to give you more information about your script.

Creating a Custom Debugging Function

One of the best debugging techniques, and also one of the simplest, is using the PHP echo() function.

Using echo() To Output Useful Information

As echo() is not actually a function, but a language construct, it can be used with or without parentheses, although if you want to output more than one parameter, you cannot use the parentheses.

When you're tracking down errors in complicated blocks of code in which a lot of variables are being used, it can be hard to understand what is happening as, although you can see the variables, you cannot see what they will contain while the code is running.

It makes life a lot easier if you add extra statements to your code, which send the contents of the variables to the screen.

It's a good idea to output the line in the following format:

    echo "\$Stringname: $string <br>"; 

Note the backslash, \, which has to be included to escape the $ character. This means that the PHP engine won't treat it as a variable, and will instead send it to the screen as text.

So for example, for a variable called $testvalue, we would use:

    echo  "\$testValue : $testvalue <br>"; 

When the page is opened in the browser, it shows:

$testValue: 25

It is well worth adding a number of these statements, so you can track the value of the variable through the flow of your script. This can be extremely useful, and you will often find that the value of a variable is not what you were expecting.

For instance, if we take the following fragment of code:

    <?php      $total = $cartTotal;      $result = addVAT($total);      $result = addPackaging($result);      $result = applyDiscount($result);    ?> 

which could be used to generate a final total for invoice, the variable $result is run through a number of different custom functions. If when the code was run, the end total is incorrect, it's difficult to see exactly where in the code the error is occurring.

By adding extra echo statements, as in the following code:

    <?php      $total = $cartTotal;      echo "\$total: $total <br>";      $result = addPackaging($result);      echo "addPackaging \$result: $result <br>";      $result = applyDiscount($result);      echo "applyDiscount \$result: $result <br>";      $result = addVAT($total);      echo "addVAT \$result: $result <br>";    echo "Total Price: £$result <br>";    ?> 

It would produce output similar to the following:

$total: 100.75

addPackaging $result: 110.75

applyDiscount $result: 0.355

addVAT $result: 0.41

Total Price: £0.41

By displaying the variable $result as it moves through the different functions, you can see where the error occurs, in the above case the result from the addDiscount function is incorrect, so you would take a closer look at the code in that function.

Adding to the Debug Information with gettype()

We can now expand on this using the PHP gettype() function. This function is passed a variable as a parameter, and returns the variable's type: integer, string, etc.

So we can modify our statement to include the gettype() function:

    echo "\$testValue : $testvalue : " . gettype($testValue) . " <br> "; 

Now when the page is opened in a browser, it shows:

$testValue : 25: integer

which is more useful.

Creating a Debugging Function

Although using the above echo() statement does what we want, it's a chore if you have to keep typing:

    echo "\$testValue : $testvalue : " . gettype($testValue) . " <br> "; 

at various points in your code to check the value of variables. To make things easier, we're going to create a function, into which we'll add our code:

    <?php      function debuginfo($param1, $param2)      {        echo "\$$param2 : $param1 : " . gettype($param1) . "<br>";      }    ?> 

We can now call this function in our code using:

    debuginfo($string, "stringname"); 

So if we have a variable called $teststring, you can call the function as follows:

    debuginfo($teststring,"teststring"); 

This is much easier and quicker to type. The output for $teststring is:

$teststring : Hello World: string

Next, we'll start adding to the function to make it more useful.

Creating a Global Debug Option

It's useful to be able to leave your debug function calls in your code on a permanent basis, and it's even worth going so far as to add them as you're creating the page.

However, we don't want the debug functions to show when the page is normal use, so we are going to add a switch so we can turn the function on and off, as appropriate. We are going to use the variable $debug as our switch, and it can be set to true or false.

Adding this to our function gives the following code:

     <?php       function debuginfo($param1, $param2)       {         global $debug;         if ($debug == true)           echo "\$$param2 : $param1 : " . gettype($param1) . "<br>";       }     ?> 

We can now set $debug on our page once, and it will apply to every use of the debuginfo function. Normally, variables in the main script cannot be used inside functions. Declaring $debug as global means that it can be seen from within the function, even though it is declared outside of the function.

To turn our function on, we use:

 $debug = true; 

To turn it off, we use:

 $debug = false; 

We can now activate or de-activate the debuginfo() function by setting the one variable. If you don't declare or set the variable $debug in your main script, then by default the debuginfo() function is turned off.

To set up the script so that you can quickly turn on the debuginfo() function using the page URL, add the following code:

     $debug = $HTTP_GET_VARS['debug']; 

if your normal page URL is:

http://www.mywebsite.com/testpage.php

You can turn on the debuginfo() function by using the URL:

http://www.mywebsite.com/testpage.php?debug=true

This only works if $debug is not set to false in your main script. It's very useful however, as it allows you to turn on debugging and check the status of your page, without having to make a change to the code and uploading the page again.

Adding Array Support Into the debuginfo() Function

Next we're going to add to the debuginfo() function, so that it can handle arrays which are passed to it.

The new code is shown below:

    <?php    function debuginfo($param1, $param2, $param3){      global $debug;      if ($debug == true){        if (gettype($param1) == "array") {          if (count($param1) > 0 ) {            echo "              <table width='200' border='1' cellspacing='0' cellpadding='0'>              <tr>              <td>              <table width='100%' border='0' cellspacing='2' cellpadding='2'>              <tr>              <td><b> \$$param2 </b></td>              <td><b> line: $param3 </b></td>              </tr>                 ";            foreach($param1 as $key => $value){              echo "                <tr>                <td> $key </td>                <td> $value </td>                </tr>                   ";            }            echo "              </table>              </td>              </tr>              </table>                 ";          }        } else {          echo "\$$param2 : $param1 : " . gettype($param1) . " line number:    $param3<br>";         }      }    }    ?> 

First of all, we've added an extra parameter, $param3, which is going to hold the line number that the variable occurs on. We can now access the debuginfo() function with:

 debuginfo($variable, "variable name", line number); 

We've also added a test to see if the variable that is passed to the function is an array, using the PHP gettype() function. We next check that the array isn't empty, in which case we ignore it by using the PHP count() function, which counts the number of elements in an array. We then send out some HTML code to create a table in which we can show the element keys and values. Look at the block of code that writes out the array's element details:

           foreach($param1 as $key => $value){             echo "                   <tr>                  <td>$key</td>                  <td>$value</td>               </tr>"; 

We use foreach to loop through each element of the array, creating a new table row for each line. This means that the code creates as many table rows as necessary to show the array's elements.

Creating a Debugging Include File

To tidy our code further, we are going to move our debugging function into a separate include file. Open a blank page, and cut and paste the debuginfo() function (including the PHP tags <?php and ?> ), into the new page. Save the new page as include/debug_helper.php.

So now we have the debuginfo() function in an include file, all we need is the following code to load our include file, and then set the debug status:

    <?php include_once("../include/debug_helper.php"); ?>    <?php $debug = true; ?> 

This code can be inserted onto any page to make the debuginfo() function available. We've used the PHP function include_once() as it's a good habit to get into. Errors can be caused by loading in an include file more than once, which could happen on a page with a lot of code and a lot of include files. As its name suggests, include_once() ensures this doesn't happen and makes sure each include file is opened once by the page, so should be used in preference to the ordinary PHP include() function.

debuginfo() in Action

Next we're going to show debuginfo() in action, by creating a simple form consisting of 3 fields: name, age, and level. The code for the whole page is shown below:

    <?php include_once("../include/debug_helper.php"); ?>    <?php $debug = true; ?>    <html>      <head>        <title>Using the debuginfo function</title>      </head>      <body>      <form name="form1" method="post" action="<?php echo "$PHP_SELF" ?>">        <table width="25%" border="0">          <tr>            <td>name:</td>            <td>              <input name="name" type="text" ></td>          </tr>          <tr>            <td>age:</td>            <td>              <input name="age" type="text" ></td>          </tr>          <tr>            <td>level:</td>            <td>              <select name="select">                 <option value="1" selected>Level 1</option>                 <option value="2">Level 2</option>                 <option value="3">Level 3</option>                 <option value="4">Level 4</option>              </select>            </td>          </tr>          <tr>            <td>&nbsp;</td>            <td>              <input type="submit" name="Submit" value="Submit"></td>          </tr>        </table>      </form>    <?php      debuginfo($HTTP_POST_VARS, "formdata", 42);    ?>    </body>    </html> 

First we start with a blank HTML page. Add the following code above the <HTML> tag:

    <?php include_once("../include/debug_helper.php"); ?>    <?php $debug = true; ?> 

We then create a simple form with the three fields above, and set it to submit back to itself using:

    <?php echo "$PHP_SELF"; ?> 

for the form action. This automatically inserts the name and path of the current page when the script is run. Below the form we added the following PHP code:

    <?php      debuginfo($HTTP_POST_VARS, "formdata", 42);    ?> 

$HTTP_POST_VARS is the array we're sending to the debuginfo() function, formdata is the reference name we're giving the data and 42 is the line number the debuginfo() function is on.

Next we upload the new page to the server and load it in a browser. We then enter some test data, and submit the form, which gives the following result.

click to expand

As you can see the debuginfo() function prints the form field names and values in a nicely formatted table.

Expanding debuginfo() Further

Although we used a very simple example to show debuginfo() in action, it can be extremely useful, and can help you see the variables during the script execution, so you can quickly spot errors.

debuginfo() is still quite simple, and there are many ways it could be expanded further, such as adding code to log the variables to a text file, instead of printing them to the screen, or only showing certain variable types, etc.

After a while, you'll soon have an ever-expanding debugging facility, to help keep your pages error free.

Two Brains Are Better Than One

It's often harder to spot errors in your own code, as opposed to another programmer's, as you know how the code is supposed to function, and it can be hard to see past this, and to see what the code is actually doing.

If you have a friend or colleague who also programs in PHP, it can be a good idea to swap code with errors. Not only can someone else probably spot the errors quicker than you can, but they can also give their opinion and suggest ideas you may not have thought of.

SQL Errors

Errors in your SQL can be resolved more easily if you print your SQL query to the screen, again by using the echo() function. This way ensures you can see the actual query that's being sent to the MySQL server, including the parts of the query that are dynamic and change at runtime.

If you're building a complex SQL query, it can be best to build it in segments, starting with a basic query and then testing that, and then adding extra parts to the query, testing after each part, until the final query is completed. This way is quicker and easier than trying to debug a complex query.

Where To Seek Help

If you get totally stuck with an error, or have any questions about PHP, there are a number of excellent resources available on the Internet which can help you.

Macromedia Forums

The Macromedia forums should really be your first port of call, if you have any questions or problems when using Dreamweaver MX. They contain a large number of friendly, helpful people, who are more than likely to be able to help you. Just searching through the appropriate groups can give you quick answers to your questions. The forums are available through your browser on the web, or through your newsreader.

There are groups for each Macromedia program, as well as subgroups in some cases, and they are "staffed" by Macromedia users, and also members of the Team Macromedia program, so you're sure to find the help you need.

Full details and addresses for the forums can be found at the Macromedia web site at http://www.macromedia.com/.

Web Sites

There are a large number of PHP-related web sites on the Internet, with new ones frequently appearing:

  • http://www.php.net/

    This as the address suggests, is the home of PHP, and is an excellent resource for everything related to PHP. You can download the manual, latest build version, as well as patches and security fixes.

  • http://www.mysql.com/

    This is the home of MySQL, and has the MySQL manual available for download, as well as the latest news and developments, and the latest versions.

  • http://www.zend.com/

    Zend is the other home of PHP, and it is the Zend Engine that powers PHP 4. Again you'll find a copy of the PHP manual, searchable by function name, as well as a huge number of helpful articles and tutorials.

  • http://www.macromedia.com/

    The Macromedia site contains all the latest news from Macromedia, as well as a large support section containing articles and tech notes for Dreamweaver MX. You should also take a look at the Macromedia Exchange, which hosts a large number of free extensions to expand the abilities of Dreamweaver MX, including a number of PHP extensions.

  • http://php.faqts.com/

    This site contains a constantly growing database of PHP questions and answers, which are sure to help answer your questions.

  • http://www.phpbuilder.com/

    PHP Builder is another excellent PHP resource, with articles, code libraries, forums, and other helpful items that can help with your PHP problems.

Newsgroups

There are also a number of newsgroups dedicated to PHP. Newsgroups are a lot faster moving, and messages are posted 24 hours a day. As a result, posting your question to one of the PHP groups can get you a much quicker response, and faster answers to your questions.

  • alt.php

    Newsgroup for discussion of anything PHP-related.

  • alt.php.sql

    A newsgroup for discussion of PHP and SQL.

  • alt.comp.lang.php

    Another PHP-related newsgroup.

Another useful resource is the experimental front end for all of the PHP mailing lists, which can be found at: http://news.php.net/.



Dreamweaver MX PHP Web Development
Dreamweaver Mx: Advanced Php Web Development
ISBN: 1904151191
EAN: 2147483647
Year: 2001
Pages: 88

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net