PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Debugging Your Web Application

To Debug Or Not To Debug

The first thing to decide is what areas of your application you wish to debug. The areas this web site is capable of recording are:

  • SQL
    • Query errors (e.g. invalid SQL)
    • Select statements
    • Delete statements
    • Update statements
    • Insert statements
  • Cache
    • Cache reads
    • Cache writes
    • Cache cleans
  • Amazon Product requests
  • Errors

In a production environment, it would be unwise to debug all of these - imagine how large your log file would be if every single SQL statement was logged. That is why I only debug errors for the live version of the site.

I sometimes record all other SQL queries in development just to get an idea of all queries being executed and looking for possible improvements or optimizations.

This site uses Amazon to fetch the data about books and publications – sometimes errors occur and we also track these.

Next, we need to turn each of these different debugging areas into code. We use defines for this, as the values never need to change and they are easily available in the global scope. It also gives us a human-readable name for the debug level.

We refer to each define as a “switch” (think of it like a lightswitch, if the switch is off we’re not debugging that section, if it’s on, we are).

Each switch value must be a power of two – this lets us turn on any or all of the switches (we’ll get to that later).

Another good practice is to prefix each switch with DEBUG_, and then within that name for the area they relate to (e.g. all SQL related switches would begin with DEBUG_SQL_).

This code should be placed in a globals file (or some file that is visible to all other PHP scripts in your application).

Listing 1 listing-1.php
<?php
    define('DEBUG_SQL_SELECT' , 1);
    define('DEBUG_SQL_INSERT' , 2);
    define('DEBUG_SQL_UPDATE' , 4);
    define('DEBUG_SQL_DELETE' , 8);
    define('DEBUG_SQL_ERROR'  , 16);
 
    define('DEBUG_CACHE_GET'  , 32);
    define('DEBUG_CACHE_SAVE' , 64);
    define('DEBUG_CACHE_CLEAN', 128);
 
    define('DEBUG_AMAZON'      , 256);
    define('DEBUG_AMAZON_ERROR', 512);
?>

We can also make a few other switches just to make our lives a bit easier, such as one for no debugging, one to debugging everything, or one to debug say, anything SQL related.

To do this, we use the bitwise ‘OR’ operator so combine the values.

Note: rather than specifying every level explicitly for our DEBUG_ALL flag, just pick a high power of 2 and then subtract 1, this ensures all the bits are “switched on”.

Listing 2 listing-2.php
<?php
    define('DEBUG_NONE', 0);
    define('DEBUG_ALL', 65535);
 
    define('DEBUG_SQL_ALL', DEBUG_SQL_SELECT | DEBUG_SQL_INSERT | DEBUG_SQL_UPDATE |
                            DEBUG_SQL_DELETE | DEBUG_SQL_ERROR);
 
    define('DEBUG_CACHE_ALL', DEBUG_CACHE_GET | DEBUG_CACHE_SAVE | DEBUG_CACHE_CLEAN);
 
    define('DEBUG_AMAZON_ALL', DEBUG_AMAZON | DEBUG_AMAZON_ERROR);
?>

This might be a little over the top, but you get the idea. You can also create other variations which may make your life easier.

Listing 3 listing-3.php
<?php
    define('DEBUG_ERRORS', DEBUG_SQL_ERROR | DEBUG_AMAZON_ERROR);
?>

The other thing we have to define is what we actually want to debug.

This part works basically identically to PHP’s error reporting (see php.net/error_reporting)

Here are a few examples (note that there should only be one occurrence of defining the debug level):

Listing 4 listing-4.php
<?php
    // debug all errors
    define('DEBUG_LEVEL', DEBUG_ERRORS);
 
    // debug all SQL related stuff
    define('DEBUG_LEVEL', DEBUG_SQL_ALL);
 
    // debug cache gets and amazon errors
    define('DEBUG_LEVEL', DEBUG_CACHE_GET | DEBUG_AMAZON_ERROR);
 
    // debug all SQL except for select statements
    define('DEBUG_LEVEL', DEBUG_SQL_ALL & ~DEBUG_SQL_SELECT);
?>

The bitwise operators can get a bit complicated. There’s a tutorial at the Java web site: Shift and logical operators

In This Article