Codementor Events

Deprecations and Changes for PHP 7.3 [Avoid Errors]

Published Nov 27, 2018Last updated Feb 01, 2019
Deprecations and Changes for PHP 7.3 [Avoid Errors]

Are you ready to embrace the new changes that will come with the publication of PHP 7.3?

In this blog post, I will guide you through the process of updating your code so that you will avoid mistakes and keep working as smoothly as possible.

Introduction

There is not so much left to the official date of the release of PHP 7.3 the new version of our favorite programming language,
as a Web Developer, I'm excited and worried at the same time.
As you already know if you read the other post I have published, with the new version, new features have been added that will facilitate the work and improve the quality of your code but at the same time when you are up to date you have to keep an eye on features that are not compatible anymore and that will cause problems to the code already existing.
In this post,
I share exactly what you need to know to start migrating your applications successfully,
including:
Remove all the features that will be deprecated and cause an error if you keep them and give you an insight of new improvements like the new system to hash passwords and create constants
Sound like a plan? Let's get into it!

Follow the series …

This blog post is the third part of "PHP 7.3 and its Christmas gifts"
If you did not read the other parts yet
You can check the other blog posts following the links below 
Introduction to PHP 7.3 and new Syntax
New features of PHP 7.3
Deprecation and Changes

Deprecations

Removing of image2wbmp()

deprecated.png

Let's start by breaking the name of this function down!
Image - 2 - wbmp ()
I must say that the purpose of this function is quite straightforward.
Wbmp format also known as Wireless Bitmap is monochromatic image optimized for mobile devices.

bool imagewbmp(resource $image [, mixed $to [, int $foreground]]);

This function accepts 3 parameters (the resource, a string with the path to the saved file and foreground colour in integer format) and returns a boolean value depending on the outputs of the saving of the wbmp version of the image provided.
The reason why this function has been deprecated and it will be definitely deleted in the future version of PHP is that there is already a function that has exactly the same functionality.

It is imagewbmp(),
From a quick research on GitHub imagewbmp and image2wbmp.

You will see that imagewbmp() has much more usage rate, so what the creators did was just eliminate the less used.
From the next version of PHP each call to image2wbmp() will throw a deprecation warning whereas later on in the following version, when it will be definitely deleted, it is going to throw a fatal error.

In order to update your scripts, if you are using image2wbmp(), what you need to do is simply to replace it with imagewbmp(),
The code will do the same and there will be no warning or errors.

FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED Deprecated

These two are flags that belong to the filter_var() function.
filter_var() filters variables with the flags specified by the web developers.

mixed filter_var(mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]]);

The first parameter is the variable that needs to be filtered or validate,
the second parameter is called flag and contains the ID of the filter that needs to be applied.

Here is the list of all the type of filters available in PHP.
The third parameter its mandatory and need to be in form of an array or a bitwise disjunction of flags.
If you are unfamiliar with the square brackets, what they mean is that the parameters insides are not mandatory and you can avoid inserting them being sure that you will not get any error.

In case of the filter parameter, the reason is that by default PHP will user FILTER_DEFAULT.
And here is what changed on PHP 7.3.
Since PHP 5.2.1 these two flags are included in FILTER_VALIDATE_URL even though you do not specify them.
To sum up,
these two constants are useless and as written in the RFC they have created the wrong impression that either the scheme and the host can be disabled.
If you have code the use these two flags somewhere remove them and you are good to go.

Deprecate case-insensitive constants

At the moment, version 7.2 of PHP supports either case-sensitive and case-insensitive constants.
The letters are not used frequently but when used they cause inconsistencies.

bool define(string $name , mixed $value [, bool $case_insensitive = FALSE ]);

The last parameter of the function is a boolean and if set to TRUE the constant is going to be defined as a case-insensitive.
Which means SANTA and Santa will represent different values.
As the name,
Constants must be constant, which means they cannot change after they have been declared.
This rule is not true in case of case-insensitive constants.

define('SANTA', 42);
var_dump(SANTA); // int(42)
define('SANTA', 24); // Notice: Constant FOO already defined
var_dump(SANTA); // int(42)

If case-sensitive and case-insensitive constants are mixed:

define('santa', 42, true);
var_dump(SANTA); // int(42)
define('SANTA', 24);
var_dump(SANTA); // int(24)

The previous code actually changes the value of the defined constant, which is not a behaviour that we want.
There will be various differences in PHP 7.3:
The possibility to define the third parameter as TRUE has been deprecated and will be definitely removed in version 8.0.0;
It won't be possible to access a case-insensitive constant with a format that is different from the one used in the define function anymore.

define('Santa', 'Claus', true);

The previous code will throw "Deprecated: define(): Declaration of case-insensitive constants is deprecated",
In case you try to access the constant just defined using another casing it will result in "Deprecated: Case-insensitive constants are deprecated.
The correct casing for this constant is "Santa"
Unlike the other updates,
to fix all the possible issue with the code you need to do a few resources.
You must be looking for all the constants declared case-insensitive.
The good news is that you have to declare the constants that way outright just check for define function with the third parameter set as true.

Changes

PCRE to PCRE2 migration

Perl Compatible Regular Expressions, also called PCRE is a library that PHP uses for dealing with Regular Expressions.
PCRE is composite as a set of function that implements regex pattern matching the same syntax and semantics of Perl 5,
it cannot be disabled anymore.
The problem arrives when you realize that PHP still uses version 1.0 of the library that has been unutilized,
At the same time the new version, PCRE2 was released in 2005.
This is mainly a core functionality of PHP, thus for the most, it won't affect the user of the language but you need to be aware of some modification that may affect how you work with PHP currently.
Here are some of the differences
Modifier S is now on by default. PCRE does some extra optimization.
Option X is disabled by default. It makes PCRE do more syntax validation than before.
Unicode 10 is used, while it was Unicode 7. This means more emojis, more characters, and more sets. Unicode regex may be impacted.
Some invalid patterns may be impacted.

In simple words,
PSRE2 is more strict in the pattern validations, so after the upgrade, some of your existing patterns could not compile anymore.
Here is the simple snippet used in php.net

preg_match('/[\w-.]+/', ''); // this will not work in PHP7.3
preg_match('/[\w\-.]+/', ''); // the hyphen need to be escaped

As you can see from the example above there is a little but substantial difference between the two lines.
The hyphen now needs to be escaped,
this probably is one of the most common causes of incompatibility you will encounter.
Also, PHP does not lint regex during the linting time,
It is advised to check all the regex you are using in your applications and test them with PHP 7.3.
Exakat.io provides a complete list of the regex inventory
Implementing this new feature may be a little bit more problematic than the other seen previously,
in fact, some calls to preg_match() could stop working.
Before upgrading your PHP to the 7.3 version I advise to check it and, in case, update or rewrite the pattern you need.
Also,
run your unit test to find errors during compilation.

Undefined variables in compact()

compact() is an amazing array function that allows the creation of array by using the name of one or more variables as parameters.

$name  = "Claus";
$title = "Santa";
$residency = "North Pole";
$result = compact("name", "title", "residency", "reindeer");
Array
[
    [name] => Claus
    [title] => Santa
    [residency] => North Pole
];

In the previous example, the variable $result is an array and contains the name of the variable selected in the form of keys and the values of the variable selected in the form of value.
During the last decade, because of the exponential use of PHP frameworks, and since the fact that the latter use template engine on MVC models,
The use of this function has been increased quite a lot.
A characteristic that this method did provide until version PHP 5.3 is that if we insert a string that refers to a variable that does not exist, the script will simply ignore the parameter.
In the long run, and especially with distracted web developer this used to cause missing variables in the views (in case of MVC) or missing data in general.
With an outstanding 32 vs 5, finally, after installing the new version of the programming language, compact() will start to report these missing variable with the following notice.

// Notice: compact(): Undefined variable: reindeer

Please be careful because when updating your current projects you may encounter a large number of the just mentioned notices.
In case fixing all the instances result overwhelming a good idea might go back to the old situation by using the @ operator and fixing the case one by one.

Argon2 Password Hash Enhancements

cybersecurity-strategy-passwords-header.jpg
It is a good thing that developers always work on enhancements over security and password hashing.
Strive to achieve a better level of protection is of fundamental importance especially when talking about our data.
PHP 7.2 implemented a new hashing algorithm called Argon2 that is meant to be an alternative to Bcrypt.
Argon2 comes in three different versions
They are:
Argon2d that is the fastest among them, it uses data-depending memory access maximizing resistance to GPU attack.
Argon2i instead uses data-independent memory access, it is preferred for password hashing but it is slower because of sasses over the memory in order to protect from attack
Then we have Argon2id which is the version that combines the other two versions

In PHP7.3 you will have the possibility to add the constant PASSWORD_ARGON2ID as a flag of the password_hash() function.

password_hash('password', PASSWORD_ARGON2ID);

There are several details about this new method like parallelism factor, memory cost and time cost calculations but I will save you them and simply showing you the syntax you can use in case you want to opt for this type of hashing.

$options = ['memory_cost' => 1<<11, 'time_cost' => 4, 'threads' => 2];
password_hash('password', PASSWORD_ARGON2ID, $options);

Another function that accepts this new algorithm is password_needs_rehash() that check whether the supplied hash implements the algorithm and the option provided and return a boolean accordingly.
Example:

$hash = password_hash('password', PASSWORD_ARGON2ID);
password_needs_rehash($hash, PASSWORD_ARGON2ID, ['memory_cost' => 1<<17]);

Conclusion

In this article,
I have provided a deep summary of all the relevant changes and improvement that will be featured in the next version of PHP,
If everything goes as planned It will take just another few days before these changes are officially released (PHP 7.3 is forecast for December the 13th).
Meanwhile you are waiting for these updates (it can be frustrating I now) there are several expedients that you can apply in order to be ready for them.
First,
you can update your code, checking and removing every incompatibility with the new version,
You can see on each section of each new feature if there are any backward compatibility problems, a good idea would be to go throw all the sections of this article (I remind you that it is devided in 3 main components) and find out if they are supported in your code.
An example could be getting all the regex in your code and linting them with the new PCRE2.
You can use polyfill for PHP 7.3
Also, run Exakat and look for issues.
Eventually,
of course, run your unit test.
If you do not have any test in your application and you do not use automated testing,
write the test then run them!.
Last note: the full list of PHP 7.3 proposals on the RFC and GitHub's PHP 7.3 Notes are available on these links.

Going back on my Christmas,
It is weird how when you, as a child sneak under the Christmas tree hoping to
get a new pair of boots to flaunt in the next football match, or the last video game that will keep you awake for entire nights while trying to kill the boss.
Whereas now, you wait for December to get new features on your favourite programming language.
But, you know.
As a grown-up person,
I am sure you understand that learning this stuff will make our job easier, that result in less stress in and out of the office which means a happier life to spend with your loved ones,
Which eventually is the real unique spirit of Christmas.
So,
even though is not time yet Happy Christmas and a happy new codes.

subscribe-Medium.jpg

front-cover-KDP.jpg
This blog post is a section of the Kindle book "PHP 7.3 and its Christmas gifts"
click the link provided to get the full version

Discover and read more posts from anastasionico
get started