Thursday, July 8, 2010

Why you want PHP-5.3.2

In this post, I'm going to spend some bytes telling you why PHP-5.3(.2) is awesome. The goal is to get you wanting to type echo "=dev-lang/php-5.3.2" >> /etc/portage/package.keywords followed by emerge php after reading this.

In my current little survey, 6 out of 7 who have voted so far, said that their code is ready for PHP-5.3. So they probably know about the goodies already and hopefully have already tried Gentoo's all new and shiny php-5.3.2 ebuild or even the php-5.3.3 RCs Ole maintains in our overlay.

For the rest of you, I'll highlight some points of the PHP-5.3 migration list:

Late Static Binding

Here's what the PHP website says: [...] can be used to reference the called class in a context of static inheritance [...] So far, so unclear. But it continues:
[...] static:: will no longer be resolved using the class where the method is defined but it will rather be computed using runtime information.

This is most useful in a class hierarchy, where your (abstract) base class does most of the work, but needs bits of information from the child class. Using static::, you can call back to methods of your child class from the base class without your base class having to know about the particular child class at all! This saves you numerous instanceof tests.

I use this in a MVC-Framework, where a BaseController holds a generic way to generate pagination data and forward it to the view. It also collects cookie and database information to save and restore user's preferences. This forced the cookie and database query methods into the ChildControllers, as the particular cookie or database column name was specified there. With PHP-5.3 I can now access those bits via static:: calls in the base class! No need for code duplication anymore.


Closures

If PHP-5.3 had contained no new features but this one, I'd still be happy. Closures are a powerful concept, but as the Late Static Binding above, can take a little bit of time to get into. In short, you can do everything you could do with create_function but instead of hiding all your code in a big string (loosing all the syntax highlighting and error checking of your editor), you now have perfectly valid PHP code inside a function you can declare about anywhere you could use a statement. You can assign your function like so:

$f = function($v) { return $v*$v; }
$f(2); // 4

Or you can use it directly, like so:

$squares = array_map(function($v){ return $v*$v; }, range(1,10));

This even saved me some precious horizontal space compared to array_map(create_function('$v', 'return $v*$v;'), range(1,10));

For additional coolness, you can let the closure use data from the parent scope (the context it is defined in, not the one it is run in), something you could achieve using create_function and embedding the extern variable in the string - it's so ugly I won't repeat it here. But look at the cleanliness of the closure approach (taken from the PHP manual):

$callback =
function ($quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};

array_walk($this->products, $callback);

You definitely want to give closures a try!


Ternary default operator

Folks have lobbied long and hard for this. In short, it's your well-known ternary operator (bool ? if-true : if-false) shortened to return the evaluated ("bool" in my case) statement if you supply nothing for the "if-true" part but "bool" actually evaluated to true. Here's an example:

return 'gentoo is cool' ?: 'who wants to read this, anyway?';

This will return "gentoo is cool", as a non-zero-length string evaluates to true and nothing was given to be return in this case.


New date/time functions

Not much to see here: you can now use date_add(), date_diff() and date_sub() for which I've been waiting for ever since I needed to display dates and calculate expiry times. strtotime() is good for a lot of things, but sometimes you need more.


Misc

Some new stuff I still need to test out:

  • The new mysqlnd library now returns correctly typed data instead of strings only for a query result

  • SPL gained a host of basic data structures like Heap, PriorityQueue or Stack
  • Phar archive support is now shipped with PHP




As expected, some things stopped to work in PHP-5.3 - they are documented in the list of Backward Incompatible Changes. The most notable changes for my code were various array functions (like usort) not accepting anything besides arrays anymore and call_user_method() now issuing E_DEPRECATED notices. Also note that the POSIX regular expressions are now deprecated in favor of Perl regexes.

That's it for now, I hope you're on your way to emerge php (if you haven't done so already)!

No comments:

Post a Comment