Insert at the beginning of an array in PHP

Posted on Tuesday, February 16th, 2010 under ,

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…

Unit testing & TDD

Posted on Wednesday, December 2nd, 2009 under , ,

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.

Backslash hell

Posted on Thursday, November 26th, 2009 under , , ,

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 :(

Debugging PHP with FirePHP on Zend Framework

Posted on Thursday, October 1st, 2009 under , , , ,

firephpYou know the saying: if debugging means taking the bugs out, then programming means putting them in. Yes. We all have bugs in our code. And since not all of them can be marketed as “undocumented features”, from time to time we have to debug our applications.

The best debugger for PHP I’ve used so far is Zend’s. Zend Platform together with Zend Studio constitutes a very good development environment and a great debugging environment. Due to the fact that Zend Studio is a little pricey, I don’t use it any more, instead I’m using a highly customised vim. This makes a great development environment, but unfortunately isn’t not that great when debugging. I know you can use vim with Xdebug, but it’s quite a chore, and I don’t like it. Since old school debugging with var_dump() or print_r() is out of the question, I was looking for another way to debug my applications. And I’ve found just the thing: FirePHP. It’s a Firefox extension, just like FireBug – that can receive debug information from the server.

Since I do most of my bugging programming on Zend Framework, I also need debugging for this platform. I use the OOP based bootstraping method, where you extend your Bootstrap class from Zend_Application_Bootstrap_Bootstrap. And in the .htaccess file of the /public/ directory, I have an envelope with the current state of application (usually on of development/staging/production):

SetEnv APPLICATION_ENV development

Normally, I need the debug information only when the application is in the “development” state, so I’m using this method in the Bootstrap class.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
    // Bootstrap other components
 
    /**
     * inits FirePHP for debugging
     *
     * @return void
     */
    protected function _initFirebugDebugger() {
        if(APPLICATION_ENV == 'development') {
            // don't debug while not in "development"
            $logger = new Zend_Log();
            $writer = new Zend_Log_Writer_Firebug();
            $logger->addWriter($writer);
 
            Zend_Registry::set('logger',$logger);
        }
    }
}

I also like to have some syntactic sugar when developing, so I’ve define this function in the Bootstrap.php file. Yes, I know that this might be perceived as a blasphemy by some of the OOP purists out there, but I really don’t care. If you don’t want non-OOP “stains” on your code, simply create a YourApplication_Utility_Firebug class or whatever with a static debug() method and paste the code in it.

/**
 * syntactic sugar for logging errors
 * and debug messages to FireBug
 *
 * @param string $message
 * @param int $label
 * @return void
 */
function fb($message, $label = null) {
    if($label != null) {
    	$message = array($label, $message);
    }
 
    if(Zend_Registry::isRegistered('logger')) {
    	Zend_Registry::get('logger')->log($message);
    }
}

And now, any time you need to debug something, simply type:

fb($variable);
fb($_POST); // and so on

And all these variables will be sent to Firefox’s FirePHP toolbar and you can inspect them from there. For even better results, you can also send debug information from your ErrorController to FirePHP (comes in handy when using Ajax).

PS: I’ll have a look into FireLogger for PHP. It also look pretty interesting, although it’s only in Beta.

Zend Framework SameAs validator

Posted on Tuesday, September 29th, 2009 under , ,

While working on a Zend Framework project, I’ve found myself in need of a “same as” validator. If you’re familiar with Zend Framework’s form system, then you know what a validator is, if not, enhance your knowledge on the topic by reading this page from ZF’s manual.

My validator was supposed to check if the same value was entered into two password fields, to avoid the user’s typos in passwords. You know, those annoying “please re-type your password” fields. At the time, I couldn’t find a good validator for this purpose, so I’ve decided to write my own. The source code is available on Git Hub, here.

It’s quite easy to use:

// create some filters
$stringTrimFilter = new Zend_Filter_StringTrim();
$stripTagsFilter = new Zend_Filter_StripTags();
 
// other validators
$notEmptyValidator = new Zend_Validate_NotEmpty();
$notEmptyValidator->setMessage('This field is required');
 
// create the SameAs validator
$sameAsValidator = new Generic_Validate_SameAs();
$sameAsValidator->setMessage('The 2 fields do not coincide', Generic_Validate_SameAs::NOT_THE_SAME);
 
// create the main password field
$password = new Zend_Form_Element_Password('password');
$password->setOptions(
    array(
        'label'       => 'Password',
        'required'   => true,
        'filters'      => array($stringTrimFilter, $stripTagsFilter),
        'validators' => array($notEmptyValidator),
    )
);    
 
 
// add this field to the SameAs validator
$sameAsValidator->setElement($password);
 
// create the new 
$validateNewPassword = new Zend_Form_Element_Password('validateNewPassword');
$validateNewPassword->setOptions(
    array(
        'label'        => 'Re-type the password',
        'required'   => true,
        'filters'      => array($stringTrimFilter, $stripTagsFilter),
        'validators' => array($notEmptyValidator, $sameAsValidator), // add it as a validator to the second field
    )
);

If the value entered in the second field isn’t the same as the value entered in the first field, the validator will signal an error. Simple as that.

Better PHP exchange rate script

Posted on Monday, September 28th, 2009 under ,

Long, long time ago, in a galaxy far, far away :) I was searching for a way to get the exchange rate automatically and use it in a project I was working on back then. And, following the will of the Force, I’ve came up with this script, which queries Google for the exchange rate and parses the answer page with regular expressions.

The script has proven useful to a lot of people, but, several days ago, an user called Lars Sorhus posted a comment in which he posted a link to another Google service, that outputs a (malformed) JSON containing the exchange rate.

The JSON based solution is much more elegant than parsing a HTML file with regular expressions, so I went for it, but since Google’s conversion service doesn’t output well formatted json, PHP’s built-in json_decode() function won’t work, so I had to look for another parser.

I’ve settled for PEAR’s Services_JSON class for decoding the JSON, as the test said that it can parse almost anything. And it does. Here’s is an working example:

/**
 * queries Google for the current exchange rate, doesn't need cURL
 * 
 * @param mixed  $amount
 * @param string $currency
 * @param string $exchangeIn
 * @throws Exception
 * @return mixed
 */
function exchangeRate($amount, $currency, $exchangeIn) {
    $url = @ 'http://www.google.com/ig/calculator?hl=en&q=' . urlEncode($amount . $currency . '=?' . $exchangeIn);
    $data = @ file_get_contents($url);
 
    if(!$data) {
        throw new Exception('Could not connect');
    }
 
    $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
 
    $array = $json->decode($data);
 
    if(!$array) {
        throw new Exception('Could not parse the JSON');
    }
 
    if($array['error']) {
        throw new Exception('Google reported an error: ' . $array['error']);
    }
 
    return (float) $array['rhs'];
}

It uses exception, because I think that the OOP exceptions based approach is much better than return false or adding a passed by reference parameter to be used for error signaling. It’s very simple to use:

try {
	$rate = exchangeRate(1, 'euro', 'usd');
	echo 'Exchange rate is: ' . $rate;
}
catch(Exception $exception) {
	// log $exception->getMessage()
	echo 'Due to technical difficulties, we couldn\'t get the exchange rate';
}

Of course, you must include the Services_JSON.php class from the PEAR repository prior to calling exchangeRate().

Logical operators in PHP

Posted on Friday, April 3rd, 2009 under , ,

Early in his career, every PHP programmer writes code like:

mysql_query( $sql ) or die( mysql_error() );

Come on! We’ve all been there. Of course, now we all agree that that’s lame and stupid and we use PDO or even ActiveRecord, but back in the days, that was widely used. What does that mean, actually? or die()?

It’s an optimization originally implemented in – I think – gone wild.

For instance, if you have a condition like:

if ( ( $a == $b ) || ( $c == $d ) ) { /* whatever */}

…if the the result in the first set of parenthesis evaluates to true, the second one isn’t evaluated because its result is irrelevant in this context. The parser already knows the answer, as “true or anything” always equals true.

The mysql_query() function returns a value that can be evaluated from a boolean point of view. If that result is evaluated to true (the query was okay), then the die() part gets left out. If the query fails and mysql_query() returns something that evaluates as false, then the die() call gets executed. That’s all, in a nutshell.

The above code could have been rewritten as:

if ( ! mysql_query( $sql ) ) {
    die( mysql_error() );
}

Still lame, but with improved readability.

Of course, you can do nifty tricks with this kind of constructs:

is_numeric ( $_GET['id'] ) || redirect( '/my/error/url' );

Cool!

PHP on IIS

Posted on Tuesday, March 24th, 2009 under , ,

After losing the battle for world domination, Microsoft came up with a new idea: PHP on Windows. While I was reading the following paragraph:

PHP is the language that runs the web, however, for a long time; PHP had a reputation of poor performance on Windows. Thanks to the hard work of the PHP Windows team and help from their friends in Redmond, Windows is now a first class citizen for PHP deployment as well as development. We asked two of the Core Windows PHP developers what they thought about the progress that PHP had made on Windows.

…I kept hearing in my head the words of a Microsoft evangelist telling me that PHP is just a child play and “real” applications are built upon the .NET framework. Tell that to Facebook, mister evangelist!

I don’t think that this desperate attempt to get people to switch from Linux to Windows will have any success. The transition costs are enormous, too huge to even be considered. And I don’t mean MS licenses. Most of the PHP applications are bundled with bash scripts, they work with Linux mail servers as sometimes programmers “pipe” incoming mails to a PHP script and so on. All these features must be ported to Windows. All user groups in /etc/passwd with their associated rights through out the file-system must be ported to Windows. All the system administrators that are required to run those servers must be trained to work on Windows.
And why? Because Microsoft says it’s faster this way? Get the facts :) )

PHP Geek Meet

Posted on Sunday, March 22nd, 2009 under , , ,

I’ve attended the first PHP GeekMeet in Cluj (for those of you that are geographically impaired, this is Cluj). I’ve held a presentation on Zend Framework, a long yet not as boring as I thought, 2 hours long presentation. My colleague Alex Novac from Zitec also held a presentation about optimisation techniques in PHP and disassembled a simple == operator call to see what happens below . The other presentation, although not strictly PHP related, was held by Andrei Gheorghe on scalability techniques.

I consider this edition of GeekMeet to be a succes and I congratulate Mihai for it.

PS: my presentation can be downloaded here.

Zend Framework and hidden fields

Posted on Tuesday, February 17th, 2009 under , ,

One thing I really hate about forms in Zend Framework is the fact that the hidden fields are displayed as blank lines – sounds stupid but this is what really happens – and if you have more than one – let’s say 4 or 5 – their presence can become really annoying and ruin the layout. This happens because although the hidden fields aren’t shown by the browser, their wrapping tags are. ZF wraps all the form elements in additional markup with the help of decorators. The default XHTML for a hidden field in a Zend_Form looks something like this:

<dt>&nbsp;</dt>
<dd><input type="hidden" id="myElement" name="myElement" /></dd>

The definition tags have display:block, so they insert a lot of empty spaces in the layout. Which in the end will make the designer very unhappy. The solution is to remove all the definition tags or to hide them. Since this is presentational matter, it should fall to a view helper. The first idea was to remove the tags completely for hidden fields. Like such:

class Motanelu_View_Helper_FormFixer {
    public function formFixer( Zend_Form $_form ) {
        foreach( $_form->getElements() as $element ) {
            if( $element instanceof Zend_Form_Element_Hidden ) {
                $element->removeDecorator( 'HtmlTag' );
                $element->removeDecorator( 'Label' );
            }
        }
        return $_form;
    }
}

…and in the view (assuming that the helper is the the right path and will be picked out automatically by Zend Framework)…

echo $this->formFixer( $this->form );

Should do the trick. And it does. A lame trick :) If there are more elements in the form, the resulting markup will look something like this:

<form enctype="application/x-www-form-urlencoded" action="" method="post">
    <dl class="zend_form">
        <dt><label for="name" class="optional">Enter your name</label></dt>
        <dd><input type="text" name="name" id="name" value="" /></dd>
        <input type="hidden" name="id" value="" id="id" />
        <dt>&nbsp;</dt>
        <dd><input type="submit" name="submit" id="submit" value="Go go go!" /></dd>
    </dl>
</form>

Yep, that’s right! Invalid code. Not good. Another approach would be to hide the dt and dd tags that wrap around hidden fields with CSS. First attempt:

class Motanelu_View_Helper_FormFixer {
    public function formFixer( Zend_Form $_form ) {
        foreach( $_form->getElements() as $element ) {
            if( $element instanceof Zend_Form_Element_Hidden ) {
                foreach( $element->getDecorators() as $decorator ) {
                    $decorator->setOption( 'class', 'hidden' );
                }
            }
        }
        return $_form;
    }
}

But this doesn’t work as expected. The code above will produce:

<dt>&nbsp;</dt>
<dd class="hidden"><input type="hidden" name="id" value="" id="id" /></dd>

The dt doesn’t have the hidden class added to it. After some debugging, I’ve found why. It’s not a bug, it’s an…well…undocumented feature of Zend Framework.

// Zend_Form_Decorator_Label - line 306
if (!empty($label)) {
    $options['class'] = $class;
    $label = $view->formLabel($element->getFullyQualifiedName(), trim($label), $options); 
} else {
    $label = '&nbsp;';
}

I’m very curious who is the rocket scientist that came up with this idea and more important why. Why shouldn’t I be allowed to change the class of an empty label? Well, never mind…But since it’s a very bad practice to change a framework’s source code, I’ve looked for a workaround. And found one: if the element doesn’t have a label, I’ll add a blank one. Like such:

class Motanelu_View_Helper_FormFixer {
    public function formFixer( Zend_Form $_form ) {
        foreach( $_form->getElements() as $element ) {
            if( $element instanceof Zend_Form_Element_Hidden ) {
                $label = $element->getLabel();
                if( empty( $label ) ) {
                    $element->setLabel( '&nbsp;' );
                }
                foreach( $element->getDecorators() as $decorator ) {
                    $decorator->setOption( 'class', 'hidden' );
                }
            }
        }
        return $_form;
    }
}

After adding the following code to my CSS file

.hidden {
    display: none;
}

…I can finally say that it works, that all the hidden fields stay hidden and that the resulting markup will validate even against the draconian XHTML Strict specification of the W3C.