PHP Coding Tips

Debugging Output as Code Comments

Often programmers will print out a complex array to aid the task of debugging a program. Sometimes it's good idea to copy and paste that debugging output back into the source code as code comments. At a later date, you or another programmer can look at the comment to see what kind of data is available to use.

function login($username, $password) {
    $user = db_find_user($username);
    // print_r($user): Array ( [id] => 321 [username] => 'moxley' [pass] => 'XXXXXX' )

    // ...
}

Object Notation over Array Notation

$cart = array();
$cart['lines'] = array();
$line = array();
$line['sku']   = 'XYZ';
$line['title'] = "Widget";
$line['price'] = 12.00;
$line['qty']   = 1;
$cart['lines'][] = $line;

Have you ever thought: "I have this associative array here, and I'm using it like an object, but objects take more effort than associative arrays: First, I have to write and manage a class for that object. What a hassle." Here's a little secret: In PHP, you don't have to write a class to create your own objects.

Here's the same code again, refactored:

$cart = new stdClass;
$cart->lines = array();
$line = new stdClass;
$line->sku   = 'XYZ';
$line->title = "Widget";
$line->price = 12.00;
$line->qty   = 1;
$cart->lines[] = $line;

Just from visually comparing the two, one advantage comes to mind: The object version is less verbose. What's that "stdClass", you ask? That's PHP's built-in generic class. It doesn't have any member functions (methods). It's always available. It's convenient when all you want is a simple object to hold values.

More astute readers might say, "Complex arrays are still easier to populate than objects. You can't do this with objects:"

$cart = array( 'lines' => array() );
$cart['lines'][] = array(
  'sku' => 'XYZ',
  'title' => 'Widget',
  'price' => 12.00,
  'qty'   => 1
);

Actually, yes you can:

$cart = (object) array( 'lines' => array() );
$cart->lines[] = (object) array(
  'sku' => 'XYZ',
  'title' => 'Widget',
  'price' => 12.00,
  'qty'   => 1
);

It is extremely easy to convert an array to an object. Creating and initializing object is as easy as creating and initializing arrays.

There are three reasons objects can be better than associative arrays. For starters, the syntax for accessing elements is cleaner. The practise of using objects instead of associative arrays makes your programs more maintainable and flexible because objects can evolve in ways that associative arrays can't.

The third reason to use objects is that when you pass them to a function in PHP 5, they are passed by reference. This means that no matter how many functions the object gets passed to, or how recursive those function calls get, the changes made to your object inside those functions will never get lost. To make that feat with associative arrays requires all the responsible functions to handle the associative array with a special unusual syntax, using the pass-by-reference operator, '&'. It's easy to forget to use that syntax. The other benefit of passing objects by reference is that there is a performance boost in passing the reference of a large object instead of making a copy of it and passing the entire copy.

Here's an example of PHP 5's (good) habit have passing objects by reference:

$cart = get_cart();        // Get a genuine $cart object, not just a copy.
$cart->lines[0]->qty = 2;  // Make changes to the cart object that
                           // came from get_cart(). Now the cart object
                           // inside get_cart() will have that change too.

To accomplish the same with PHP 4, you would have to do something like this:

$cart = get_cart();        // Now I have a copy of the $cart object
$cart->lines[0]->qty = 2;
save_cart($cart);          // Need to explicitly save the cart

OR

$cart =& get_cart(); // Note the '&'. Now I have THE $cart object
$cart->lines[0]->qty = 2;