What’s new in PHP 5.5

[1,3,4][2], "foobar"[2] — dereferencing created arrays/strings

echo array(1, 2, 3)[0]; // 1
echo [1,3,4][2];        // 4
echo "foobar"[0]        // f

// this can be handy for quick generation:
echo 'abcdefghijk'[ rand(0,10) ]; // will get one of the letters: 'abcdefghijk'

empty() — can be applied to results of functions and expressions

Previously empty() could take only variables; now you can pass expressions themselves without needing to store the result in a separate variable:

empty( $object->get() );

list() in foreach

In foreach it became possible to use list():

$array = [
	[1, 2],
	[3, 4],
];

foreach( $array as list($a, $b) ){
	echo $a;
	echo $b;
}
// result: 1234

finally — in try/catch construction

You can throw and catch exceptions with PHP 5. This approach allows controlling code execution if there is a suspicion that something might go wrong.

And since version 5.5, a third block finally was added to this construct. The finally block is executed always after the try/catch construct finishes. It runs even when the try code threw a fatal error:

try {
	echo 'We are doing something here... ';
	// throw
	throw new Exception('Catch me! ');
}
// catch
catch( Exception $e ){
	echo $e->getMessage(); // will print: Catch me!
}
finally {
	echo 'And this is always printed!';
}

Finally is useful for convenience and additional capabilities. With it you can write less code and, for example, conveniently free up memory when needed.

A couple of demonstration examples:

Less code

Suppose we need to perform a function close() in any case, whether an exception was thrown or not:

try {
	my_function();
}
catch( Exception $e ){
	// close(); // this line would be needed without finally
	echo $e->getMessage(); // will print: Catch me!
}
finally {
	close();
}
//close(); // this line would be needed without finally

More capabilities

Suppose we opened a database connection before executing code and there is a possibility that the code will throw an error and the open connection will not close, and we need to close it in any case. finally comes in handy:

$db = mysqli_connect();

try {
   my_function( $db ); // the function's result may cause a fatal error...
}
// the exception may be left unhandled
finally {
   mysqli_close($db);
}

Class::class — to get class name in namespaces

A keyword class appeared for classes, which outputs the class name. In normal mode we don’t need it, but when working with namespaces — it’s convenient:

namespace test;
class A {}

echo A::class; //> test\A

yield — creation of generators

In simple terms: yield is like return; it also yields a value, but it doesn't terminate the function; it pauses it until the next value is requested. This makes generating generators more convenient.

Example of a generator:

function generator() {
	for( $i = 1; $i ≤ 3; $i++ ){
		yield $i; // emit a value
	}
}

foreach( generator() as $value ){
	echo "$value ";
}
// outputs: '1 2 3 '

How it actually works?

yield returns a special object — Generator. When the function generator() is called inside a loop, for example foreach, PHP will execute the function up to the first occurrence of the word yield, at which PHP will pause the function, remember the position, and yield a value (the Generator object). Then foreach will process that value and call the next() method on the Generator object. PHP will resume executing the function generator(), but starting from the last position, and again, until the yield word, which will yield the Generator object again. The loop will be interrupted when the function generator() reaches the end (does not return yield), or if it is interrupted with return;.

Example of passing a generator into a variable (repeated call in this case does not work):

function generator() {
	for( $i = 1; $i ≤ 3; $i++ ){
		yield $i; // emit a value
	}
}

$gen = generator();

foreach( $gen as $value ){
	echo "$value ";
}
// prints: '1 2 3 '

// Fatal error: Uncaught Exception: Cannot traverse an already closed generator
foreach( $gen as $value ){
	echo "$value ";
}

Example of a generator that returns a pair: key/value:

function generator( $input ){
	foreach( explode('.', $input) as $part ){
		list( $num, $name ) = explode(' - ', $part );

		yield $num => trim($name);
	}
}

$input = '1 - one. 2 - two. 3 - three';

foreach( generator( $input ) as $num => $name ){
	echo "$num ($name) ";
}

Brief about generators

  • Do not add new language features
  • Faster
  • Resuming a generator happens from the last yield
  • You can send values and exceptions into a generator (via throw())
  • Generators are one-way; you cannot go back
  • Less code in most cases, simpler constructs

API for password hashing

Now PHP out of the box offers a proper way to hash passwords. The new password hashing API provides four functions:

  1. password_hash() — used to hash a password. In WP there is a dedicated function wp_hash_password().

    $hash = password_hash( $passwod, PASSWORD_DEFAULT );
  2. password_verify() — used to verify a password against a hash. In WP there is a dedicated function wp_check_password().

    if( password_verify( $password, $hash ) ){
    	// Success!
    }
  3. password_needs_rehash() — used to check whether it is necessary to create a new hash.

  4. password_get_info() — returns the name of the hashing algorithm and various parameters used during hashing.