php55
PHP 5.5 was released on June, 20th and soon after we made it available on ServerGrove VPS images. Since then, many users have upgraded their virtual servers to PHP 5.5 taking advantage of its performance improvements, bug fixes, and several of its new features. Here are some of the new features that stand out:

Generators

Generators basically provide a simple way of implementing iterators. Any function which contains a yield statement is automatically a generator function.

Imagine you want to iterate a list of millions of numbers. Without iterators, you would have to create a huge array first and then iterate over it, which would consume a lot of memory. You can avoid this scenario by using iterators as values are yielded instead of using arrays. Generators are the best way to create iterators without all the overhead.

<?php
function getList($number) {
    for ($i=0;$i<$number;$i++) {
        yield $i;
    }
}

foreach (getList(10000000) as $number) {
    echo "$number ";
}

The output:

0 1 2 3 4 ...

I created a very simple benchmark to compare the memory usage for 10,000 numbers, enough to see the difference:

Creating array: 26.60 Mb
Generator: 12.60 Mb

Try-catch… finally!

Try-catch blocks now support a finally block for code that should run regardless of whether an exception has been thrown or not. This also ensures that the finally block is executed even if an unexpected exception occurs.

<?php
try {
    $db = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
}
catch (Exception $e) {
    echo 'catch' . "\n";
}
finally {
    echo 'finally';
}

In case the database connection fails, catch and finally blocks will be executed. If it’s successful, only the finally block will be executed:

// database connection fail
catch
finally

// database connection ok
finally

empty() accepts expressions

How many times have you tried doing something like empty($user->getName())? It is a bit annoying having to create a new variable with the return value and passing it to empty(). In PHP 5.5, this is finally possible. The empty() function now accepts arbitrary expressions:

<?php
echo (int) empty(0) . "\n";
echo (int) empty(1) . "\n";
echo (int) empty('') . "\n";
echo (int) empty('hello') . "\n";
echo (int) empty(empty(empty(0)));

The output:

1
0
1
0
1

If you are wondering why the last line returns 1/true, remember that empty() considers empty results: “”, 0, 0.0, “0″, NULL, FALSE and array(). So empty(0) is true, empty(true) false and finally empty(false) is true.

As a curiosity, the original RFC included isset() as well, but after further discussion the PHP internals team decided to only add expression support for empty().

Array/string deferencing

Static arrays and string literals can be dereferenced to access individual elements and characters.

<?php
echo [1, 2, 3][0] . "\n";
echo array(1, 2, 3)[1] . "\n";
echo 'hello'[0];

The output will be:

1
2
h

Class name resolution via ::class

Prior to PHP 5.5, if we wanted to get the fully qualified name of a class we had to use Reflection or instantiate the class to pass it to the get_class() function. It was a common practice to create class constants to overcome this limitation (e.g. ClassName::CLASS_NAME). Now, it is possible to use ClassName::class to get the FQN of the class ClassName.

<?php
namespace Foo;
class Bar {}

echo Bar::class;

The output will be:

Foo\Bar

It’s important to know that class is a keyword, not an special class constant nor a magic method.

foreach support for list() and non-scalar keys

The foreach control structure has been improved with two new features: unpacking nested arrays with list() and non-scalar keys.

With list(), nested arrays can be unpacked into variables, which improves readability:

<?php
$values = [[1, 2], [3, 4]];
foreach ($values as list($a, $b)) {
    echo $a . '-' . $b . "\n";
}

The output:

1-2
3-4

For non-scalar keys, an Iterator must be used, as they cannot occur in native PHP arrays yet.

OPcache extension added

The Zend Optimiser+ opcode cache has been added to PHP as the new OPcache extension. OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request. This extension is bundled with PHP 5.5.0 and later, and is available in PECL for some older PHP versions (5.2, 5.3 and 5.4).

Password hashing API

A new password hashing API has been included in PHP 5.5 which makes much easier to hash and manage passwords. It provides functions to hash a string, get information from a hash, verify it and check if needs to be rehashed.

<?php
$hash = password_hash('servergrove', PASSWORD_BCRYPT); // create hash
echo $hash . "\n";
var_dump(password_get_info($hash)); // get hash info (algorithm and options)
var_dump(password_needs_rehash($hash, PASSWORD_BCRYPT)); // check if hash implements the algorith and options provided
var_dump(password_verify('servergrove', $hash)); // check hash matches the password
$2y$10$w8wcuJEW6/5oVWG6CMBZB.woCUL1tkVHa6eM5S1x1DNWezxW2uUNu
array(3) {
  ["algo"]=>
  int(1)
  ["algoName"]=>
  string(6) "bcrypt"
  ["options"]=>
  array(1) {
    ["cost"]=>
    int(10)
  }
}
bool(false)
bool(true)

This new API aims to be easy to use, secure, and forward compatible if algorithms change in the future. Anthony Ferrara, the core PHP developer who proposed this new API, wrote a really interesting post about the design of the API. The RFC has also very good content about the API and cryptography.

GD

Some improvements have been included in the GD extension. Especially important is the WebP format support, which provides a lossless and lossy compression for images on the web.

This post is also available in: Spanish