Today, finally, the release of PHP 7.4 is published!
Its new features have already been repeatedly described, including on Habr. These are arrow functions, typed class properties, and much more syntactic sugar. But most of all, we were waiting for a new release because of performance: in version 7.4, not only preload appeared, but PHP itself became much faster.
Bad (or good?) News – with the release of PHP 7.4, active support for PHP 7.2 ceases. His latest release is scheduled for mid-December. We have been experimenting with PHP 7.4 for a long time, and recently we are actively engaged in the transition to it, since now we are on the almost unsupported version 7.2.
Congratulations to all on the long-awaited release! And below I’ll talk a little about how we upgrade to the new version.
Despite the fact that we have a huge code base, we have been living in PHP for 13 years. We have repeatedly had to upgrade to new versions, and the transition process is well-established.
If greatly simplified, we can distinguish several steps:
- We ensure that unit tests begin to pass successfully on the new version.
- We make the test runs on the new version mandatory for all code changes (so that you do not have to repeat step 1, since the new code is constantly written, and it may again be incompatible).
- We switch to the new version of the development platform, fix problems and live for some time in this state.
- Repeat this for staging.
- We spread it smoothly on different production clusters.
Our edits in the PHP repository
Problem with preload (fix)
This time, something has changed in the process: since we were waiting for preload, we started to carry out part of the work back in July, during version 7.4.0beta1. As a result, this resulted in a rather large amount of time spent debugging for us, because PHP 7.4 was then completely raw. But on the other hand, as a result, we found an unpleasant bug, fixed it and sent the fix to the upstream, which helped the whole community.
Then it’s time to do the tests.
Problem with access to private properties (fix)
PHP Fatal error: Cannot access private property ClassLoader::$classMap in vendor/composer/ClassLoader.php
Access to the private property of a class is carried out only inside it, but PHP reports an error: you cannot access the private property as if the call came from another class.
The problem was complicated by the fact that it was reproduced unstably. A long debug with gdb showed that really for some reason EG (fake_scope) doesn’t have the class within which the property is accessed, but another that is not related to it.
After we found a minimal reproduce case (which, for a moment, requires three classes, an autoloader and Reflection), fixed the cause of the problem and started pushed it in the upstream, it turned out that this problem has existed since PHP 7.3 (most likely, after this change), the whole world lived with her for a year and she did not bother anyone before us.
Fix Badoo Code Incompatibility
Now we are correcting all incompatibilities of our code with PHP 7.4. The vast majority of incompatibilities for us (more than a hundred places,> 80% of all incompatibilities) were caused by the addition of the “Trying to access array offset on value of type null / bool / int” error (corresponding to RFC). It occurs when using the syntax of accessing an array element on other data types.
The following example illustrates the problem well:
$a = false; var_dump($a[‘somekey’]); // PHP 7.3: // NULL // // PHP 7.4: // Notice: Trying to access array offset on value of type bool in Command line code on line 1 // NULL
Offhand it seems that this should not occur in real code, but, as practice has shown, this is a fairly common case: for example, a function can return an array in the normal case and false / null in case of an error, and further up the stack information about false / null is lost, and this case is not handled separately.
This is a rather weakly propagated, but useful change in PHP: it allows you to find many potential errors in the code.
The second update in terms of problems brought up is a change in the way method_exists () works. By the way, at the moment there is no information about it in the release notes or upgrading guide. Its essence is as follows:
class A1 { private function priv() {} } class B1 extends A1 {} var_dump(method_exists(B1::class, 'priv')); // PHP 7.3: bool(true) // PHP 7.4: bool(false)
This feature, again, is hard to come across in real code. But, as it turned out, we unintentionally actively exploited this in tests.
Of course, we are confronted to different degrees with other incompatibilities, including numerous changes related to reflection (example one, example two), changes to hexdec () and the like, prohibition of array_key_exists () even for ArrayAccess objects, with incompatibilities in various dependency libraries connected via Composer, and even with all sorts of exotic things, compulsory such as stream_set_option () for stream wrappers that have become mandatory for include wrappers. But in sum, the costs of adapting to all these changes cannot be compared with the case of using the syntax of arrays on non-arrays.
At the moment, we have finished working with unit tests: they fully pass in PHP 7.4. We are working on API tests and plan to start switching between different clusters and environments by the end of the year.
Summary:
I want to invite to this discussion for discussion: have you already tried PHP 7.4? If so, what was your experience like? Are you going to cross?
12 comments
Thanks. And the performance measurements were / will be – version lower and 7.4?
In this article We talked about our experiments. In short, on the test endpoint PHP 7.4 gave + 10% in comparison with PHP 7.2, the inclusion of preload gave another + 10% from the top.
How much will be in reality – we will find out when we move on, and perhaps share the results if they are interesting. 🙂
Prod was transported when 7.4RC6 came out.
Faced with a memory leak problem in the parallel (issue) extension – we are waiting for the reaction of krakjoe, the author of the extension and the php developer.
There are also problems with typed properties when deploying a test database from Doctrine fixtures. Entity :: $ property must not be accessed before initialization, with $ em-> flush (), when receiving uninitialized entity lazy-objects from the fixture reference repository
Yes, this is generally understandable :). The question is, how much effort did they have to make? Is it easier than editing the runkit / uopz extension? In github.com/badoo/soft-mocks, unfortunately, I do not see edits for PHP 7.4 for the time being (maybe I was not looking there).
PHP 7.3 was already very fast and convenient. With Laravel, it’s just sweetie, but 7.4 is CAKE. I already tried this version of the language in practice and the indicators are surprising … I advise everyone to upgrade to the new version, you won’t regret it!
Let’s say, if in vanilla PHP the difference in query speed is not large, but in Laravel, when I’m executing all the data from the database, the difference in speed is somewhere around 60-76 ms. In my opinion, in large projects, every millisecond counts. And yet, the medium forum has officially announced that prior to PHP-v8.x, they will upgrade exclusively for frameworks. Let’s see what happens…
Hi! This is kind of off topic but I need some advice from an established blog. Is it very difficult to set up your own blog? I’m not very techincal but I can figure things out pretty fast. I’m thinking about setting up my own but I’m not sure where to start. Do you have any ideas or suggestions? Many thanks
I truly appreciate your work, Great post.
I’ve recently started a blog, the information you offer on this website has helped me greatly. Thanks for all of your time & work. “Yield not to evils, but attack all the more boldly.” by Virgil.
Some really good content on this website, thank you for contribution. “Careful. We don’t want to learn from this.” by Bill Watterson.
Simply wanna tell that this is handy, Thanks for taking your time to write this.
Yay google is my king assisted me to find this outstanding internet site! .
How Can I Trade Altcoins for Profit?
Prime numbers – how great is our powerlessness?