PHP 7.1: better syntax, a more consistent language

September 12, 2016php, php-7.1, english

Cet article est aussi disponible en français.
This is the 6th post in a series about PHP 7.1.


A new version of PHP is always the right time to fix or enhance some syntax specific points, or to add some minor new features to the language. Here are some of the changes for PHP 7.1 that I noticed the most.

Allow specifying keys in list()

The first one is about the list keyword and extracting data from an array: list() now accepts the keys of the items we want to extract.

For example, to only get the items at 'glop' and 'who' keys from an array containing three entries, we can now use the following syntax:

$array = [
    'glop' => "Hello",
    'plop' => 123456,
    'who' => "World",
];

list (
    'glop' => $a,
    'who' => $b
) = $array;

var_dump($a, $b);
// string(5) "Hello"
// string(5) "World"

The approach is safer and easier to read than the one we were using before, only based on the position of each item in the array.

‣ The RFC: Allow specifying keys in list()


Square bracket syntax for array destructuring assignment

Since PHP 5.4, we can work with a short syntax to build arrays: [10, 20, 30]. Starting with PHP 7.1, we can also use this short syntax to deconstruct arrays, without using the list keyword:

$array = [10, 20, 30];
[$a, $b, $c] = $array;
var_dump($a, $b, $c);
// int(10)
// int(20)
// int(30)

This is, of course, compatible with what I wrote before:

['glop' => $glop, 'plop' => $plop] = [
    'plop' => 42,
    'glop' => "Hello",
];
var_dump($plop, $glop);
// int(42)
// string(5) "Hello"

Well, this is not a revolution, but it’s always nice to see more consistency in the language!

‣ The RFC: Square bracket syntax for array destructuring assignment


Generalize support of negative string offsets

Another small evolution, which makes PHP more consistent with itself and with other languages and will in some situations simplify things a bit: support for negative indexes, when working with strings, has been generalized.

This means we can now use a negative index to access a character inside a string, counting from its end:

$str = "Pascal";
var_dump($str[2]);  // string(1) "s"
var_dump($str[-2]); // string(1) "a"

As a reminder, with PHP 7.0, the last line would have returned an empty string.

This syntax also works to change a specific character, where PHP 7.0 would have raised a warning:

$str = "Pas.al";
$str[-3] = 'c';
var_dump($str);  // string(6) "Pascal"

Several string-related functions have been updated and now accept counting from the end of the string. For example:

var_dump( strpos("Pascal", "c", -5) ); // int(3)

Here too, PHP 7.0 would have raised a warning, BTW.

‣ The RFC, which lists all updated functions: Generalize support of negative string offsets


Class Constant Visibility

I often need to define an internal constant in a class — and I often see this need while doing code reviews.

For this, with PHP 7.0, we have two options:

  • Defining a class constant with const: we have the advantage of using a constant, we cannot change its value, but it is necessarily public.
  • Or setting up a private static variable: we have the advantage of a private piece of data, which will not be available outside of the class (it’s not part of its API), but it’s a variable and not a constant.

PHP 7.1 answers this and we can now specify visibility on class constants:

class MyClass {
    public const MY_PUBLIC = 42;
    private const MY_PRIVATE = 1234;

    public function test() {
        var_dump( self::MY_PRIVATE );
    }
}

Of course, the three public, protected and private keywords keep the meaning they already had for attributes and methods:

var_dump( MyClass::MY_PUBLIC ); // int(42)
(new MyClass())->test(); // int(1234)

// Fatal error: Uncaught Error: Cannot access private const MyClass::MY_PRIVATE
var_dump( MyClass::MY_PRIVATE );

Here’s an evolution that could seem minor at first sight, but I already know I will use it ;-)

‣ The RFC: Support Class Constant Visibility


You liked this post? Spread the word!

This blog has recently been migrated to a static site generator and I haven't had time to setup a commenting solution yet.

With a bit of luck, I'll manage to take care of this in a few weeks ;-)