Tudor Barbu's blog

Ramblings about software development

This is a post I’ve been wanting to write for a while but I didn’t quite get the time to do it. It’s about me finally taking the ZF certification exam. I wanted to take this certification for over an year and a half, but first I postponed it because I was learning python and working with Django and I didn’t have the time to actually look over Zend Framework’s manual and read it. Then I moved to Spain, got caught up with other problems and so on, and so on…

Thing is that I bought a voucher for this exam about an year ago, and, as most Zend issued vouchers, it only lasts one year. So, few weeks ago I found myself with an already paid non-refundable voucher bound to expire. Since I had nothing to lose, I decided to take my chances and take the exam. And I did :) Hooray for me!

About the exam

The Zend Framework is much more “to the point” than the PHP 5 and it’s a piece of cake for the seasoned Zend Framework developer. No more “which comes first: the needle or the haystack?” questions. Everything is focused on asserting the fact that the candidate has the knowledge required to be productive using ZF. The topics cover a large part of the ZF manual, with focus on commonly used features. This doesn’t mean that you shouldn’t pay attention to more “exotic” topics like Zend_Memory, Zend_TimeSync or Zend_Wildfire. Although the test refers to version 1.5 of Zend Framework – the current version is 1.11 – there’s nothing specific to that version and the questions refer to those features that are common throughout all the versions (MVC, coding standards, plugins, validator chains, etc).

PS: don’t email me asking for the questions to the test! Go study…

31 Aug

PHP switch

Posted by Tudor. Tags: , ,

Over the years, I’ve encountered a lot of strange things in PHP, but this one is off the scale:

$value = 'zero';

switch ($value) {
    case 0:
        echo 'value is zero';
        break;
    default:
        echo 'value is not zero';
        break;
}
echo PHP_EOL;

What do you think that the code above will print? Well…I’ll spare you the hassle and give you the answer:

% php test.php
value is zero

This weird behavior originates in the fact that PHP uses the equality operator (==) instead of the identity (===) one when evaluating expressions inside a switch statement. It’s basically the same as:

if ('foo' == 0) {
    echo 'bar';
}

…which also yields unexpected results. I hate this type of casting!!!

Problem: we have an hierarchy of 3 classes, each extending the one in front (grandfather, father, son). A method – let’s say foo() – is defined in the grandfather class and overridden with a new functionality in the father class.

Question: Is there a way in the son class to access the original method (with the grandfather code) in the son class?

Of course, the obvious solution is to try something like:

parent::parent::method();

But it won’t work. It will just yield an error like:

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in …

After some struggling, I have found a way to get around and access a method from the grandparent class that was overridden in the parent and run its “original” code. It’s loosely based on the strange PHP scoping that I wrote about in this article. The approach goes something like this:

class Grandfather
{
    protected $_message = 'Luke, I am your grandfather';

    public function say()
    {
        echo $this->_message;
    }
}

class Father extends Grandfather
{
    protected $_message = 'Luke, I am your father';   

    public function say()
    {
        throw new Exception("I can't breath under this f**cking mask :( ");
    }
}

class Son extends Father
{
    protected $_message = 'I have a very bad feeling about this';

    public function say()
    {
        Grandfather::say();
    }
}

$son = new Son();
$son->say();

Now PHP will bind the $this pointer in the body of the say() method – using the code defined in the grandfather. I guess that weird scoping is there for a reason.

09 Jul

PHP 5.3 certification beta-testers

Posted by Tudor. Tags: ,

Zend is looking for beta-tester for its new PHP 5.3 certification programme. If you’re interested, all you have to do is simply take this survey and provide your contact details (so that they can find you).

How do you remove empty elements from a PHP array? The answer’s quite simple: array_filter(). Straight from manual and works like a charm:

$filtered = array_filter($raw);

Well, most of the time. It’s not recursive by default, so it only removes empty items on the first level of the array. If you have nested arrays and wish to remove all the empty items, regardless of their position in the matrix, array_filter() won’t work.

For example, let’s consider the following construct:

$raw = array(
    'firstname' => 'Foo',
    'lastname'  => 'Bar',
    'nickname' => '',
    'birthdate' => array(
        'day'   => '',
        'month' => '',
        'year'  => '',
    ),
    'likes' => array(
        'cars'  => array('Subaru Impreza WRX STi', 'Mitsubishi Evo', 'Nissan GTR'),
        'bikes' => array(),
    ),
);

In this case, PHP’s built in array_filter() will miss the “birthdate” and “bikes” items. So, what now? Of course, you can create a function that will remove empty items recursively and pass it as a callback to PHP’s array_filter() function:

function removeEmptyItems($item)
{
    if (is_array($item)) {
        return array_filter($item, 'removeEmptyItems');
    }

    if (!empty($item)) {
        return true;
    }
}

$filtered = array_filter($raw, 'removeEmptyItems');

But if you’re using a framework like Zend Framework that forbids using functions in the global scope and asks that all functions are wrapped in classes as static methods, things become more complicated and verbose. Yeah, yeah, I know, I’m a standards nazi :)

But if you’re using PHP 5.3, there’s a much simpler solution:

$callback = function($item) use (&$callback) {
    if (is_array($item)) {
        return array_filter($item, $callback);
    }
    if (!empty($item)) {
        return true;
    }
};

$filtered = array_filter($raw, $callback);

Lambdas are sweet :)

01 Jun

Constants for table names

Posted by Tudor. Tags: ,

While working on a PHP project, I had the following idea: wouldn’t be better to use constants for table names? I mean, having a file, let’s say /application/config/tables.php, which would look something like:

define('TABLE_USERS', 'users');

And afterwards, use this value throughout the application:

…in the associated Zend_Db_Table_Abstract

class Users extends Zend_Db_Table_Abstract
{
    protected $_name = TABLE_USERS;
}

…in joins:

$this->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
 ->setIntegrityCheck(false)
 ->join(TABLE_USERS, sprintf('%s.id = %s.user_id', TABLE_USERS, $this->_name));

…in the forms:

$validator = new Zend_Validate_Db_NoRecordExists(
    array(
        'table' => TABLE_USERS,
        'field' => 'email',
    )
);

This makes much more sense to me, since writing a simple ‘users’ string can be interpreted as a “magic number“…well…string and it’s very hard to maintain, should one want to, let’s say, prefix some of the tables in the database with their module’s name.

For example, if there’s already an “users” table in system and, in a new module, there’s the need for another “users” table, it would be less confusing to prefix the old table it’s called “old_module_table” and the call the new one “new_module_table”. Encapsulating the table’s name into a constant makes this really easy. I think I’ll use this in my next project.

11 May

Strange PHP scoping

Posted by Tudor. Tags: , ,

I came to the conclusion that PHP is the programing language with the weirdest features. After the variable variables mess, that allows to you to name your variables stuff like !@#$%^&*()_+= and not be able to use them directly, I thought I saw everything. But no, yesterday I’ve bumped in another strange PHP feature. An even stranger feature.

Take a look at the code below:

class Example
{
    public function dynamicMethod($string)
    {
        // calls method baz() of the same class
        // class Example *does not have* a baz() method
        $this->baz($string);
    }
}

class Foo
{
    public function bar()
    {
        // a dynamic method called statically
        // no Example object is being instantiated
        Example::dynamicMethod('whatever');
    }

    public function baz($string)
    {
        echo 'Method baz() called with param "' . $string . '"' . PHP_EOL;
    }
}

$foo = new Foo();
$foo->bar();

What do you think the code will do? Yield an exception? A syntax error? Work? Well, strangely enough, it works:

Tudor-Barbus-MacBook% php blog-example.php
Method baz() called with param "whatever"

…and it seems that this feature is here to stay and be supported in the future, since I’m using the new PHP 5.3 version:

Tudor-Barbus-MacBook% php -v
PHP 5.3.1 (cli) (built: Feb 11 2010 02:32:22)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

I wonder how this can be useful to somebody.

Last week, while programming, I needed to insert an array at the beginning of another. So, since basically I was just merging 2 arrays, I tried to do it like this:

$originalArray = array(
    1 => 'First item',
    4 => 'Forth item',
    5 => 'Fift item',
    10 => 'Tenth item', // and so on
);

$insertAtBegining = array(
    0 => 'None',
);

$newArray = array_merge($insertAtBegining, $originalArray);

But it didn’t work. :( It was displaying something like:

Array
(
    [0] => None
    [1] => First item
    [2] => Forth item
    [3] => Fifth item
    [4] => Tenth item
)

Not a good result, because the arrays’ keys were actually primary keys used by the RDBMS so it was very important for me to keep the original keys. I didn’t want to take the lame approach and do a foreach loop:

$newArray = $insertAtBegining;
foreach($originalArray as $key => $value) {
    $newArray[$key] = $value;
}

…because it was too obvious, so I did something less obvious, and much more complicated:

$newArray = array_combine(
    array_merge(array_keys($insertAtBegining), array_keys($originalArray)),
    array_merge(array_values($insertAtBegining), array_values($originalArray))
);

But in the end, Chris, one of my colleagues who also has a blog at SegmentationFault.es pointed out the most simple and elegant solution:

$newArray = $insertAtBegining + $originalArray;

This reminds me of the saying “Keep It Simple Stupid” :) Which Chris uses as a wallpaper…

02 Dec

Unit testing & TDD

Posted by Tudor. Tags: , ,

Last week, I had a discussion with Ionut – my colleague at Ninespices – about a piece of code I had wrote in one of our applications. The piece was meant to log the current user’s actions to the database for future reference. It looked something like this (more or less, the actual code isn’t that important):

protected function _log($info) {
    $identity = Zend_Auth::getInstance()->getIdentity();
    $this->save(
        array(
            'user_id' => $identity->id,
            'info' => $info,
        )
    );
}

Ionut said to me: “I don’t like it! It’s hardcoded!”. I said that it’s not, as I don’t hardcode anything, since we all know that each time one hardcodes something in a software application, God kills a kitten.

But Ionut asked me a simple question: “How do you test it? How do you mock Zend_Auth?”. For the record, Ionut is the Test Driven Development guy of the team. He always writes tests for his applications, whereas I don’t, since my code “just works”…well, kind of…sometimes :) . The point he made is interesting: how do you mock Zend_Auth? The answer is obvious: D’oh, you don’t!

In order to be able to properly use unit testing to test a piece of code, that code must be written in a manner that allows unit testing. To make a method “testable”, you must not instantiate other objects, call other classes’ static methods and so on. For instance, let’s consider a piece of code that looks like this:

public function methodThatRequiresTesting($input) {
    // get data on the current logged user
    $identity = Zend_Auth::getInstance()->getIdentity();
    $userId = $identity->id;

    // instantiate a helper class
    $helper = new MyLibrary_Helpers_Foo();

    // do whatever
}

It’s quite obvious that this code isn’t “unit testing friendly” as you cannot mock the helper or Zend_Auth. The proper way to write it in order to be “unit-testable” is either:

public function methodThatRequiresTesting($input, $userId, MyLibrary_Helpers_Foo $helper) {
    // do whatever
}

…or…

public function methodThatRequiresTesting($input) {
    // get the user id
    $userId = Zend_Registry::get('userId');

    // get the helper
    $helper = Zend_Registry::get('Helpers/Foo');

    // do whatever
}

This way, one can easily add mocks instead of the actual objects, isolate the functionality of this particular method and test it. Of course, the first “testable” code is wrong, as it breaks separation of concerns. A method should have input and output, and any additional entities (functions, classes) used inside the method’s body in order to compute the output from the input should be encapsulated within the method. Receiving these entities as input is a very bad practice, for obvious reasons.

The second code example is better from an architectural point of view, but it can be quite memory intensive, as one might instantiate a lot of helpers and place them in the registry without ever using them, thus wasting valuable system resources.

That very night, Ionut & I went to the 26th edition of Wurbe, where one the the topics was – beside the crappy beer – Test Driven Development. There was a somewhat heated debate on whether to use TDD or not, unit testing, functional (system) testing and so on. I particularly liked one of the opinions expressed there – by a guy who’s name I forgot :) – on functional testing. There’s no need to write unit tests for all your components. Only write tests for those components which contain complicated algorithms, so each time you refactor the code and optimise the algorithm, you know if what you did is good or not. And write a system test, in the end, to test the whole application.

It makes more sense to me this way.

26 Nov

Backslash hell

Posted by Tudor. Tags: , , ,

How do you write a regular expression that will match \\test – two backslashes followed by some text in PHP? Well, obviously you’ll try something like this:

echo preg_match('/^\\([a-z]+)/', $word) ? 'match' : 'no match';

…but it won’t work. Furthermore, it will yield an error saying something like:

Compilation failed: unmatched parentheses at offset …

And it makes sense, since the backslash has a special meaning, as it’s the escape character, to give it a literal meaning you have to escape it. Like such:

echo preg_match('/^\\\\([a-z]+)/', $word) ? 'match' : 'no match';

…each of the two backslashes is escaped by another backslash placed in front of it. But this also doesn’t work :) The correct way to do it is:

echo preg_match('/^\\\\\\\\([a-z]+)/', $word) ? 'match' : 'no match';

Yeap. That’s right! With 8 backslashes. For each backslash you wanted matched, you need to add 4 in the regular expression. That’s because the backslash is considered to be an escape character by both PHP’s parser and its regexp engine. So, if you type a backslash in PHP, it’s considered and escape character by PHP’s parser.

If you write two backslashes in PHP, this construct will be interpreted as a literal backslash by PHP’s paser and sent to the regexp engine as an escape character. That’s right: ‘\\’ in PHP means a ‘\’ for the regexp engine. So, in order to pass a literal backslash to the regexp engine, you need to add 4 backslashes in PHP.

This is what I call backslash hell :(