What was changed in PHP 7.2 DEVPARK
Development

PHP 7.1 was released 9 months ago so it’s time to look at upcoming PHP 7.2 release. At the moment of writing this article PHP 7.2 is in Beta 3 version  Looking at releases of previous versions and release plan for PHP 7.2  I think we should expect the final release until the end of year, probably at the beginning of December 2017.

Backward incompatible changes

Trait properties bug was fixed

I will start with the bug I’ve reported a few months ago which I found when I was learning to Zend Certified Engineer exam . The testing code is like this

Looking at documentation http://php.net/manual/en/language.oop5.traits.php#language.oop5.traits.properties you can read:

If a trait defines a property then a class can not define a property with the same name unless it is compatible (same visibility and initial value), otherwise a fatal error is issued.

So we would expect we get a fatal error in such situation. However in both PHP 7.0 and PHP 7.1 as output we are getting:

and we are not getting fatal error. This is because non-strict comparison was done here and 2 == true. If we changed 2 to 0, we would get fatal error right away.

In PHP 7.2 this behaviour was fixed and it’s now working as we would expect looking at PHP documentation . Now strict comparison is done, so when running script in PHP 7.2 you will get fatal error like this:

Casting array to object change

When we want to cast array to object and we use the following code snippet

in PHP 7.1 we will get the following output:

So in fact we cannot access foo or bar values because in array they have integer keys. However output for the same snippet in PHP 7.2 would be:

So as you see since PHP 7.2 we can access those values without any problem. Also notice that we cannot just use:

to display such property. We need to add curly brackets.

Casting object to array change

Very similar thing was done when casting object to array. Let’s look at the following code snippet:

Running this code in PHP 7.1 you will get:

As you see when we cast object to array in array we are getting key with string 0, and we cannot access it. We can try both $array[0] or $array[‘0’] but in both cases we will get the notice.

However in PHP 7.2 the following piece of code will output

So as you see, now in array we have integer key 0 and we can access value without any problem.

Changes for unquoted strings

Let’s look at this code snippet:

Obviously you can see unquoted string test here. In PHP 7.1 output of the script would be:

but in PHP 7.2 the output would be:

As you see it’s not a big change (Notice was changed into Warning), however in PHP 8 it will probably cause an error.

The main cause of this change is not stopping just support for unquoted string but to avoid serious problems when you typo some PHP keywords.

For example look at the following code snippet:

As you see displaying errors was turned off. What will $numbers array contain? Surprisingly the output of the script is:

and we would expect rather

This is because of typo in continue keyword and in real application this typo could cause serious problems. PHP 7.2 won’t help to avoid such problems but PHP 8 should.

Looking from other perspective, how often do you have such typos in your code nowadays, when most of us are using IDE like for example PhpStorm. And we all ave unit and integration tests for everything, right?

Object keyword not for class name

What is quite surprising for me, in PHP 7.1 the following code snippet would work without any problem:

However in PHP 7.2 it won’t work any more as object keyword cannot be used any more as class name. So in PHP 7..2 you will now get:

Fatal error: Cannot use ‘object’ as class name as it is reserved in …

Output of json_decode for object as array

Another changes was made json_decode. If you use the following  code snippet:

in PHP 7.1 as output you will get:

but in PHP 7.2 as output you will get:

This is because now, json_decode respects  JSON_OBJECT_AS_ARRAY also in case when 2nd argument is set to null

New features

Parameter Type Widening

Let’s start with code snippet

So we have some Vendor class (that represents 3rd party library) and Custom class that was created only to extend functionality of sum method. The sum method in Vendor class just sums array of numbers. However we wanted also to be able to pass some object that we can convert to array to sum, for example our Data structure.

So far so good, in both PHP 7.1 and PHP 7.2 the output will be:

as expected. However let’s assume Vendor class was changed a bit by 3rd party. Type hinting was added to this method and now this class looks like this:

The problem is that in PHP 7.1 the signature should be exactly the same. So when you updated the Vendor class and the method sum has now type-hinted $numbers, in all child classes it should be also added like this, otherwise warning will be raised:

So in PHP 7.1 you need to decide – either you won’t use new version of Vendor library or you need to adjust your code. Obviously in above case it’s not just adding type hinting to $numbers parameter in Custom class. Now, because it’s type hinted, you cannot pass Data object any more. So you need to change also they way you pass data into sum method.

Fortunately in PHP 7.2 you won’t have this problem any more. No warning will be raised and code will work without any problem. So you can update 3rd party library and you can adjust your code whenever you want to have exact same signature for class methods as parent classes. It seems as quite a big improvement and will allow to add type hinting to commonly used Composer packages without worries that it will break thousands of applications when they will update to newer version.

Abstract class parameter type widening

In similar way as parameter type widening, you might wanted to change abstract class signature a bit. Let’s look at sample code:

As you see in AbstractCustom class you remove type hinting from sum class and then you implement this in different way in your class. In PHP 7.2 this code will work now without any problem, but in PHP 7.1 and before you cannot repeat the same abstract method in child abstract class, so you was not able to widen parameter type at all. When running above code in PHP 7.1 you will get:

Probably this is smaller improvement (it won’t be used so often) I think however it’s again one extra thing that will be possible to do in PHP 7.2 and in case you need it you won’t need to create some workarounds or duplicate code just to make it work.

Group use statements trailing comma

Probably many developers use trailing comma in multiline arrays like so:

It helps adding new elements to arrays and also make diff smaller in case you add any new element. Using the same logic PHP 7.2 now supports trailing comma for group use statements like this:

The following code will work without any problem in PHP 7.2 and will allow to easy import any new class from Test namespace. Obviously this is not possible in PHP 7.1 and before.

Object type-hinting

As of PHP 7.2 we  can now use object keyword in type-hinting function arguments or return value. So for example we can use now the following code:

and it will return

in PHP 7.2. In PHP 7.1 and earlier as object was not restricted keyword and it could be used as class name it was not possible and running above code will raise error:

Sodium extension as part of PHP core

In PHP 7.2 new cryptographic Sodium extension was added to PHP core. What we can read about this library on web page:

Sodium is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more.

It is a portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further.

Its goal is to provide all of the core operations needed to build higher-level cryptographic tools.

PHP 7.2 is probably the first programming language that will add this library to core . I’m not cryptography expert but Sodium seems to be library that is highly ranked by people who deal with security, so it is really good to have it on board in PHP 7.2

Other changes

There are many other small changes. For example each function has been deprecated and will be completely removed in future (to be honest I’ve never used it and it’s a lot slower than foreach), __autoload has been deprecated and spl_autoload_register should be used instead (but it’s not a huge change – probably you either use composer and you don’t care about manual autoloading or you already used spl_autoload_register). Also some session changes were made, but again if you use PHP in normal way, you should probably don’t care about those changes at all. If you develop/run PHP  application in Windows, you must to notice also the minimum supported Windows versions are now Windows 7 and Windows Server 2008 R2.

Summary

To sum up, there are not many big changes in PHP 7.2. One of the most important is probably adding new cryptographic extension (Sodium) so now we have alternative to OpenSSL. Others are rather fixes and small improvements. Obviously if you are running legacy code and want to upgrade to PHP 7.2 many of small changes might be a problem but if you don’t probably you shouldn’t expect too many issues with migration.


Reference: