in Best Practices, Debugging

Bug-Free: Your Bug-Fixing Toolkit (Part 1 of N)

PHP has a large number of tools for fixing bugs and resolving underlying issues. But many people don’t know what they are, and some of them are extensions requiring installation in order to work. In this series, we’ll explore some features for debugging PHP scripts, from the most basic to more advanced.

Today we will discuss tools that ought to be in your bug-fixing toolkit already. There are three tools that everyone should already have:

  • var_dump();
  • print_r();
  • var_export();


Just The Facts: var_dump()

var_dump() is a useful function for its ability to display an array or an object. When matched with the >pre< tag, it displays a useful output. The following example is from the PHP documentation:

<?php
$a = array(1, 2, array("a", "b", "c"));
var_dump($a);
?>

This outputs:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  array(3) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(1) "c"
  }
}

As you can see, var_dump() is a useful function for viewing a variable, and can even be used to output the properties of an object.

Some limitations of var_dump() is that intergers and floats are listed as int(4) and float(3.2) which can be confusing when looking at a mixed set of data. Also, var_dump() outputs the variable directly; it cannot be captured as a string by default (you can capture it with output buffering if you so desire).

More Power: print_r()

This function is similar to var_dump() but print_r() allows for the output of a variable to be returned as a string for use by the developer in any way they want. Also, print_r() presents a little nicer formatting, with greater indentation for class and array members.

The following example is also from the PHP documentation:

<?php

$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x', 'y', 'z'));
print_r ($a);
?>

The above code produces the following result:

Array
(
    [a] => apple
    [b] => banana
     => Array
        (
            [0] => x
            [1] => y
            [2] => z
        )
)

You’ll notice a greater indentation and nicer formatting. Also, print_r() does not indicate whether the item is an interger, string, varable, etc. but outputs items directly, so you would get [0] => 4 instead of [0] => int(4) with var_dump().

Also, print_r() allows you to return the information as a string, instead of outputting it directly, by passing second boolean operator. It does this with output buffering, meaning you cannot pass true and also use ob_start(). For example:

<?php
$a = array('a','b','c',array('d','e','f'));
print_r($a); // Outputs the code directly.
$b = print_r($a,true); // Returns $a as a string to $b
?>

Parsable Code: var_export()

This is probably one of the most under-utilized functions out there. This returns a variable but has a particular unique characteristic: it presents the variable as purely valid PHP, meaning it can be copied and used elsewhere in your script. Also, var_export() can be returned as a string, using the same boolean optional second parameter as in print_r().

This example is from the PHP documentation:

<?php
$a = array (1, 2, array ("a", "b", "c"));
var_export($a);
?>

The following returns the string below:

array (
  0 => 1,
  1 => 2,
  2 => 
  array (
    0 => 'a',
    1 => 'b',
    2 => 'c',
  ),
)

Note that if you were to copy this string into a PHP script, and compile that script, it would compile properly.

One limitation of var_export() is that it does not produce useful output (or useful to me, anyway) of an object. For example, this is the output of an object with var_export():

<?php
class A { public $var; }
$a = new A;
$a->var = 5;
var_export($a);
?>

This produces the following:

A::__set_state(array(
   'var' => 5,
))

However, the PHP manual includes a number of examples for using this productively, so you can make the choice for yourself.

Summary

There are a number of debugging features in PHP that are both useful and important. These three should be staples of any good PHP developer’s toolkit, and they’re sadly underutilized when it comes to solving problems. Using them will make bug-fixing easier, faster, and more enjoyable (yes! enjoyable!) for the developer.

Correction: Elizabeth Smith writes that it’s a “little known fact that print_r with true uses output buffering.” The manual does make note of this, indicating that “[print_r()] uses internal output buffering with [the true] parameter so it can not be used inside an ob_start() callback function.”

Frustrated with your company’s development practices?

You don't have to be!

No matter what the issues are, they can be fixed. You can begin to shed light on these issues with my handy checklist.

Plus, I'll help you with strategies to approach the issues at the organization level and "punch above your weight."

Powered by ConvertKit
Brandon Savage is the author of Mastering Object Oriented PHP and Practical Design Patterns in PHP