What's new in PHP 7

PHP 7 has several notable improvements and changes, with the headlines prodominantly grabbed by impressive benchmarks showing a 100% increase in performance. In this article we'll look at five key changes in this new release, and features to look out for that have been removed or are now deprecated. 

What happened to PHP 6?

If you missed all the hype in 2014, you might be wondering what happened to PHP 6. Development for this version started back in 2005 with a goal to natively support unicode, meaning under the hood all strings would be repesented as UTF-16. This change wasn't widely supported due to the added complexity and performance issues, resulting in many developers using the more stable 5.3 release for future development. As a result, PHP 6 was eventually abandoned for a jump to PHP7 (decided on a vote to avoid confusion with 6, which was widely known to the community as a failed project). And so, we are now in the dawn of PHP7, sans native unicode support.

Performance

If you've only heard a little about PHP 7, then what you have heard was probably about performance. This is a major improvement in the new release with common applications such as Laravel showing 100% performance improvements or greater.

In a presentation by Rasmus Lerdorf (creator of PHP), he illustrates in a WordPress benchmark how PHP7 can run twice as fast as on PHP 5.6. You can view his full presentation on youtube.

Uniform Variable Syntax

Of all the changes to PHP 7, this is likely to be one that catches people out, and where legacy code will need to be updated. 

Uniform Variable Syntax refers to how a variable expression is processed. Consider the following code:

class product
{
    public $name = 'keyboard';
    public $cost = '9.99';
}

$product = new product();
$fields = ['name','cost']; echo $product->$fields[0];

We would expect this to return $product->name i.e. 'keyboard', however this is inconsistent with usual 'left-to-right' processing, meaning it should really try to process this expression as {$product->$fields]}[0] rather than $product->{$fields[0]}. In order to maintain the result in PHP 7 you would need to explicitly state how you want it to be processed using the curly brackets.

Other than consistency, this change also allows for other expressions that previously would have been invalid. Consider the following:

class foo
{
    public function bar($format)
    {
        return [
            'xml' => function ()
            {
                return '...';
            },
            'string' => function ()
            {
                return '...';
            }

        ];
    }
}

$foo = new $foo();
$result = $foo->bar()['xml']();

The above code is now functional as it is processing the result as ($foo->bar())['xml']() rather than $foo->{bar()['xml']}()

Here's some further examples to illustrate the difference in how expressions will be evaluated:

Expression Old Meaning New Meaning
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

You can read more detail on Uniform Variable Syntax on php.net.

Type Hinting

PHP is a loosely typed language in that variables do not need to be declared and do not require a specific type, unlike other popular languages like Java where variables and their types must be declared before use. In PHP 7 there are more options available to enforce specific data types. 

Since PHP 5 it has been possible to use some type hinting in function declarations like so:

function processProduct(Product $product, array $params) { //... }

This allows us to define which class type is expected by the function which is useful for dependecy injection, or if the data should be an array, but those are the only options available as of PHP 5. If you tried to set type hint as 'string' it would expect a class with that name, rather than a string data type, resulting in a fatal error.

In PHP 7 we have some more options, specifically Scalar type hints offering int, float, string and bool allowing for stricter arguments. This means the following is now possible:

function setPrice(float $price) { //... }

Note that the data passed into the function argument will be converted if it doesn't match, so if we tried to pass '9dollars' In the above example, it would strip the alpha characters. To use strict types, which will force an error if the type passed in doesn't match, you can declare the following on a file-by-file basis:

<?php
declare(strict_types=1);
//...

As well as Scalar type hinting, PHP 7 also offers return type declarations so you can specify what type of data you expect to be returned. This is achieved with a colon after the closing bracket for the arguments like so:

function getProductPrice(Product $product) : float { //... }

With the above the code is more readable and we can be sure the function is always returning the same data type. Just like the scalar hints, non-matching data will be converted to the requested type when used in non-strict mode (default).

New Operators

PHP 7 offers a couple of new operators, namely the interestingly titled 'spaceship operator', also known as the combined comparison operator, and the 'null coalesce operator'.

The spaceship operator is essentially a shortcut to comparing if one variable is greater, equal or less than another variable in a short statement like so:

$a <=> $b

This will return -1 if $a is smaller than b, 0 if the variables are equal, or 1 if $a is greater than $b.

The null coalesce operator is another shortcut to conditionally set a variable depending on if another is null:

$price = $customPrice ?? 9.99

So if the $customPrice variable is set, it will be used by $price, otherwise it will default to 9.99.

Error Handling

In earlier versions if your application throws a fatal exception, it's pretty much game over as fatal errors wouldn't invoke the error handler. This leads to an unfortunate white screen of death for your visitors. In PHP 7 this has changed, giving developers better control over this error type through use of the try catch method. This change will affect any errors that can be recovered from, meaning it doesn't apply for truly fatal errors such as running out of memory. 

Errors and exceptions can both now be caught with a new throwable class like so:

try {

   // Exception or error can be thrown here...

} catch (Throwable $t) {

   // Catches errors and exceptions in PHP7

}

Deprecated Features

Removed Deprecated Features

As you can imagine, with a new major release, several deprecated features have now been dropped. Most notably is the following:

  • Mysql extension
    All the original mysql_ functions (mysql_query etc) are no longer usable. You can easily migrate to using mysqli_ functions, or use PDO

  • Regular expression extension
    Ereg used for regular expressions is also now removed, superceded by preg_replace.

New Deprecated Features

  • Named Constructors
    Remember when your constructors used to be the same as the class name? That's finally gone too, all constructors must now use the __construct() method.

  • Static calls to non static methods
    Static methods must be labelled as static in order to be called statically, otherwise this will thow an error.

  • Password hash salt
    The salt option for the password_hash() function has been removed, replaced by automated secure salt generation.

Conclusion

In this article with covered some of the most notable new additions in PHP 7 and deprecated features to look out for. In an upcoming article we'll take a look at how you can upgrade your local machine or server to this latest version of PHP.  

Sign Up

NEXT: Create a membership site with Symfony 2

How to create basic membership functionality including registration, login and protected pages using the Symfony 2 framework.

comments powered by Disqus
Sign Up

Popular Tags

Need a web developer?

If you'd like to work with code synthesis on your next project get in touch via the contact page.