Install Xdebug on Ubuntu

I always forget the little bit about error reporting, so here is a step by step guide to getting Xdebug running on you Ubuntu PHP installation.

1) Install PECL (if you don’t have it already)

> sudo apt-get install php-pear

2) Install Pear Xdebug extension

> sudo pecl install xdebug

3) Create a new config file and have it point at the new extension. Pay attention to the location of the extension in the above image. That is the path for this step.

> sudo nano /etc/php5/apache/conf.d/xdebug.ini

Add a line (if its not already there)




4) Now, edit the PHP ini file to change the following settings

display_errors = On


html_errors = On


Done, just restart apache and you should have nice var_dumps now

How to install PEAR (Linux)

PEAR (PHP Extension and Application Repository) is a bunch of extensions you can install on your server to uitilise clever ‘extras’ that other people have spent their time writing.

To install it, sudo into a terminal console:

$> wget
$> php go-pear.phar

This should go away and get the files and install it. Now you have to find the extensions you want. They all have an identifier in the form of a string, i.e. Spreadsheet_Excel_Writer – you’re likely to find the name of it on the website that hosts the code/documentation.

Installing it is easy too:

$> pear install Spreadsheet_Writer_Excel

Done. Sometimes, a new version will come out, and the version number will be appended to the end of the name, so you might have to install it like:

$> pear install Spreadsheet_Writer_Excel-09.00.1

But, pear will tell you if this is the case, and it will tell you which version to install.

To list all the PEAR packages on your machine,

$> pear list

To remove one,

$> pear uninstall <packagename>

The place that keeps a list of the locations of the PEAR files is called a channel, and some packages are stored on a different channel to the standard, so you have to add the channel list to PEAR:

$> pear channel-discover <url>

But again, the documentation for the package will tell you if this is the case, and the URL if so.

You can read more about PEAR here – and there is a list of ‘supported’ packages here –


PHP Create a ZIP file

I was just playing around with PHP’s ability to create compressed files, and I had a problem. My ZIP file was not getting created but I wasn’t getting any errors.

$zip = new ZipArchive();
$zipFile = '/tmp/' . uniqid() . '.zip';

if (file_exists($zipFile)) {

$zip->open($zipFile, ZIPARCHIVE::CREATE);

foreach ($files as $type => $file) {


Now, pay particular attention to the files you are adding using addFile() as if you have entered them wrong, you won’t get an error message, and infact, if you use $zip->getStatusString() you will receieve a “No error” message – completely throwing you off the scent.

More information about ZipArchive can be found at

Message: [Syntax Error] Expected PlainValue, got ”’ at position x in property {model}

Was getting the above error in my Doctrine project, turned out I had used a single quote in the ORM Annotations:

     * @ORM\Column(type='integer', name='row_number')
     * @var int
    protected $rowNumber;

Your ORM Annotations must be double quotes ” to allow the read ahead to read ahead…

Should be like:

     * @ORM\Column(type="integer", name="row_number")
     * @var int
    protected $rowNumber;

Setting up Class Table Inheritance with Doctrine 2.0

Have had some serious problems getting this working, but after a 4 hour head bashing session, we’ve cracked it.

CREATE TABLE inventory(
    inventory_id INT AUTO_INCREMENT,
    discriminator_column VARCHAR(20),
    category VARCHAR(50) NOT NULL,
    part_number VARCHAR(50) NOT NULL,
    PRIMARY KEY (inventory_id),
    KEY category_part_number (category, part_number),
    KEY discriminator_column (discriminator_column)
CREATE TABLE inventory_room(
    inventory_id INT NOT NULL,
    rack_limit INT(6),
    room_type VARCHAR(25),
    KEY inventory_id (inventory_id),
    CONSTRAINT inventory_room_key FOREIGN KEY (inventory_id) REFERENCES inventory (inventory_id) 

You have to have a discriminator field so that Doctrine can connect the tables nicely when its joining them.

namespace Net\Model\Inventory;
use Doctrine\ORM\Mapping as ORM;

 * Inventory entity
 * @ORM\Entity(repositoryClass="Net\Repository\Inventory")
 * @ORM\Table(name="inventory")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discriminator_column", type="string")
 * @ORM\DiscriminatorMap({"inventory" = "AbstractItem", "inventory_room" = "Room"})
 * @category Net
 * @package  Model
abstract class AbstractItem
     * @ORM\Id @ORM\Column(name="inventory_id") @ORM\GeneratedValue
     * @var int
    protected $inventory_id;

     * @ORM\Column(type="string")
     * @var string
    protected $category;    

     * @ORM\Column(type="string")
     * @var string
    protected $part_number;

As you can see in the above class, we have a ORM\GeneratedValue field. This tells Doctrine that this field is an increment field. As this is a one-to-one relationship we do not need one in the inventory_room table as it will be joined on the inventory_id field.

In the next class, this is the child class that extends the abstract. So Doctrine will read the annotations at the top and see that its a joined table using the id field (inventory_id)

namespace Net\Model\Inventory;
use Doctrine\ORM\Mapping as ORM;

 * Inventory Room entity
 * @ORM\Entity
 * @ORM\Table(name="inventory_room")
 * @category Net
 * @package  Model
class Room extends AbstractItem
     * @ORM\Column(type="string")
     * @var string
    protected $room_type;

     * @ORM\Column(type="string")
     * @var string
    protected $rack_limit;

SVN Externals – how to add them

When creating a Zend Framework site, its always best to keep the Zend library as an external source. This way you can keep the branch up-to-date with the release of Zend with a simple text file.

To access the externals file, navigate to the root of your site:

> cd /var/www/mysite

And add the external to the svn:externals file. I am using the latest version of Zend Framework for this, but you can use any SVN source you like. Note, it has to be available as an SVN repository.

> svn propedit svn:externals .

This will open a text editor.

To enter an external, just enter the local folder to download to, and the source SVN.

destination source

So, if I want my Zend Framework files to be saved in /var/www/mysite/library/Zend :


The first part is the local, second part is the URL of the repository.

Save and close.

Next time you do an update, svn will go and fetch the external files and save them for you.

Other externals are available, such as JQuery, various wikis and other JS sources.




PHP App Testing

Think: “What am I testing?”

1) Set-up

Instantiate your class

Look for dependencies, are there any that need mocking?

2) Exercise

We test our real objects that need testing,

or mock objects that don’t but are required by SUT (System Under Test)

3) Verify

Real object results

Expectations of mocked objects

4) Tear down

Destroy objects if needed?


The four-phased testing technique explained here:


Zend Console – get values passed

When using a CLI script with options, I like to use the Zend_Console.

If my options are as follows:

$console = new Zend_Console_Getopt(
        'i-s'  => 'test option 1',
        'e'    => 'test option 2')

For instance,

> php myScript.php -i OPTION

To get the “OPTION” string for the -i parameter

$arg = $console->getOption('i');

$arg will now contain the passed option, but if none was passed, it will be NULL

When outlining the available options that can be used with your script, you use the following syntax:

long|short  => description;
test|t => 'Test the script';

You can use,

> php myScript.php -t


> php myScript.php --test

to run the -test parameter. You can also pass values, such as an integer or a string:

'test|t=i' => 'Option with required integer parameter';
'test|t-s' => 'Option with optional string parameter'

For more information, refer to the Zend Documentation :