PHP in Action Rotating Header Image

Real programming with PHP 5.3 (part 1): array processing

You may have heard of the new features that are scheduled for PHP 5.3, but who knows what they can be used for in real programming? I took the time for some experimental research, and came up with a few examples.

At the PHP UK conference, I saw Sebastian Bergmann’s presentation on lambda functions, closures and traits. Lambda functions and closures are scheduled for 5.3 (or fivethree, as I’ve affectionately named the binary), or later. The presentation was intriguing, but has only simplistic examples, sufficient to illustrate the mechanical aspects. It left me curious as to what these features could be used for in real programs.

Before we start playing, let’s get the basic terminology clear. Lambda functions and closures are two fancy names for (variations on) anonymous functions. These are functions that are more flexible than ordinary functions and can be stored in variables or defined just where they are needed.

Anonymous functions are possible even in pre-5.3 PHP. They can be created using create_function(). But this is cumbersome, ugly, error-prone and possibly insecure. PHP 5.3 lets you do this in a much more natural and pleasant way.

The most basic and obvious case is sorting. Here is an example from Sebastian’s presentation:


<?php

usort(
    $list,
    function ($a, $b) {
        if ($a == $b) return 0;
        return ($a < $b) ? -1 : 1;
    }
);

In PHP before 5.3, this must be done either by using create_function() or by defining the function somewhere else, away from where it’s actually used. The above is clearly much better.

What else can we do with anonymous functions? In Ruby, they are the standard way of processing arrays. For example, if we want to process a set of files, adding a directory name at the beginning, we can do this:

files = ['pdo.a','pdo.la','pdo.so','sqlite.a','sqlite.la','sqlite.so'];
files_with_dir = files. map  { |f| "modules/#{f}" }

The snippet inside the braces is a function. map is the Ruby equivalent of PHP’s array_map(), except that Ruby is built to do this particular trick. But let’s try the equivalent with PHP 5.3. First we define the array:

$files = array('pdo.a','pdo.la','pdo.so','sqlite.a','sqlite.la','sqlite.so');

And then we process it:

$filesWithDir = array_map(
    function($f) { return "modules/$f" ; },
    $files
);

Interesting, but not necessarily better than the conventional alternative:

$filesWithDir = array();
foreach ($files as $file) {
    $filesWithDir[] = "modules/$file";
}

Using array_map() seems like a realistic option, at least for some cases. It reads differently because it’s conceptually different, focusing on processing the entire array rather than one element at a time. You might find it cleaner. And in some cases, it will be clearly superior. If you have a slightly more complex structure than a simple one-dimensional array, you can use array_map_recursive() to simplify the code dramatically.

In part 2, I’ll present an example of a JavaScript-style class composed of closures.

Reblog this post [with Zemanta]

Share/Save/Bookmark

15 Comments

  1. Interesting to see what people come up with in regards to closures in PHP. I wrote some examples in my blog as well, but was faced with some opposition about the usefulness of them =)

    http://codeutopia.net/blog/2009/02/20/closures-coming-in-php-53-and-thats-a-good-thing/

  2. mark enriquez says:

    man call me old fashioned, but this whole “new” way of throwing a bunch of functions right on the call stack (ie javascript) of other is really rather annoying, and makes the code much harder to understand and debug.

    been using extJS lately, and they take this anonymous function stuff to the nth level…in some cases the entire code consists of one function with 23 anon function calls and objects nested inside.

    is this *really* progress? ive been programming for well over 20 years, and back in the day we put a premium on readability and maintainability, and i am sorry this style does nothing to help in those regards.

    my 2 cents,
    - mark

  3. Rian Orie says:

    I have to admit that I hadn’t heard about any new features for 5.3 at all yet so reading about it here is the first encounter I’ve had with it.

    I don’t so much think the argument should be ‘do we need them’, as I don’t see why they can’t be useful.. I think the trick will be for people to put them to proper use rather than throw them around mindlessly.

    This does open up a whole new cabinet of opportunities for people who don’t have the slightest idea on how to code to still end up with a (partially) working end result. That in result has more people write gimpish stuff and in result has people who do have an idea pull out hairs when their finally consulted to fix the apocalyptic mess in the end.

    But, as said.. there’s a use, I’m sure

  4. Nate Abele says:

    mark: I think that’s a rather simplistic view of things. Functional programming is extremely powerful, there’s nothing “new” about it, and *any* programming paradigm can be abused to create obtuse, unreadable code; including (sometimes especially) OOP. Does that mean you’d rather revert to your procedural days of 20 years ago?

  5. [...] the PHP in Action blog, a new series has been kicked off with this first part looking at “real programming” in the upcoming PHP 5.3 release. You may have heard of [...]

  6. [...] the PHP in Action blog, a new series has been kicked off with this first part looking at “real programming” in the upcoming PHP 5.3 [...]

  7. David says:

    Listing 1, Line 7 should probably be

    return ($a < $b) ? -1 : 1;

  8. Vlad says:

    For more concise mapping in PHP (pre-5.3) you can check out the project that emulates Python-style list comprehensions: http://code.google.com/p/php-lc/

  9. dagfinn says:

    You’re right. I copied it by hand from Sebastian’s slide. Fixed.

  10. [...] has a post looking at using the new closure feature of PHP 5.3. He compares using foreach for iteration versus [...]

  11. [...] the PHP in Action blog, a new series has been kicked off with this first part looking at “real programming” in the upcoming PHP 5.3 release. You may have heard of the new [...]

  12. [...] Closures = Anonyme Funktionen Beispiele gibt es hier :http://blog.agilephp.com/ [...]

  13. [...] Aquí un post explicación las bondades de las lambda functions y las closures, pero afirmando que son una alternativa a la forma clásica de escribir código, pero no una auténtica mejora. Luego escribe, una segunda parte del artículo explicando cómo escribir código PHP al estilo de jQuery. [...]

  14. [...] has a post looking at using the new closure feature of PHP 5.3. He compares using foreach for iteration versus [...]

Leave a Reply