Preloading in PHP 7.4

The translation of this article was prepared specifically for students of the Backend PHP Developer course.







PHP 7.4 adds preloading, a feature that can significantly improve code performance.



On preload in a nutshell.





Let's talk about the new feature in more detail.



More than Opcache



Yes, preloading is based on opcache, but it's not exactly the same thing. Opcache takes the PHP source files, compiles them into opcodes, and then saves the compiled files to disk.



Opcodes can be considered a low-level representation of your code that is easily interpreted at runtime. Thus, opcache allows you to skip the stage of translating the source files into what the PHP interpreter actually needs at run time. Noticeable savings!



Nevertheless, you can save even more. Compiled with opcash



files do not know anything about other files. If you have class A, which is an extension of class B, they will still need to be linked at runtime. In addition, opcache checks to see if the source files have changed, and upon detecting the changes will invalidate their caches.



And here the preload comes to the rescue: it not only compiles the source files into opcodes, but also connects dependent classes, traits and interfaces. It stores such a “compiled” fragment of executable code (that is, code that the PHP interpreter can use) in memory.



When a request arrives at the server, it can use parts of the code base that has already been loaded into memory, without any extra time.



What “parts of the code base” are we talking about?



Practice preloading



For correct preloading, the developer must tell the server which files to download. This is done using a simple PHP script, so there is nothing to fear.



Nothing complicated.





Suppose you want to preload some kind of framework. Let it be Laravel. In this case, your script should look at all the PHP files in the vendor/laravel



and add them one at a time.



Here is how you can include this script in php.ini:



 opcache.preload=/path/to/project/preload.php
      
      







And here is an example implementation:



 $files = /*  ,      */; foreach ($files as $file) { opcache_compile_file($file); }
      
      





Instead of opcache_compile_file



you can use include



. However, it seems that there was a bug here , since at the time of writing the second option did not work.



Warning that you cannot preload an unrelated class



There is a warning Can't preload unlinked class ? The fact is that before preloading files, you also need to preload their dependent objects — interfaces, traits, and parent classes.



If you encounter any problems with class dependencies, you will be warned about this when starting the server:



 Can't preload unlinked class Illuminate\Database\Query\JoinClause: Unknown parent Illuminate\Database\Query\Builder
      
      





Note that opcache_compile_file()



only opcache_compile_file()



the file, but will not execute it. This means that if a class has dependencies that have not been preloaded, then the class itself cannot be preloaded.



This is not critical: the server will work as usual, but you will not have all the files that you wanted to preload at your disposal.



That is why you need to carefully select the files for pre-loading in order to avoid dependency problems. Doing it manually is an ungrateful and time-consuming task, so developers are already working on automated solutions.



Composer support



The most promising automated solution is being prepared by composer developers, which is already used in most modern PHP projects.



Now the guys are working on the ability to configure preload in composer.json



, which in turn will generate a preload file instead of you. Like preloading itself, this feature is still under development. You can follow the development of events here .

Fortunately, you don’t have to manually configure the preload files if you don’t want to - composer can do this for you.



Server requirements



There are two other important points that a developer should keep in mind when using preload.



You already know that you need to create an entry in php.ini



for the preload to work. This means that if you use shared hosting, you will not be able to configure PHP as you like.



In practice, you will need a dedicated (virtual) server to optimize preloaded files for a single project. Keep this in mind.



Also remember that you will need to restart the server (if you use php-fpm



, this is enough) every time you want to reload files in memory. For most, this is obvious, but it will not be superfluous to recall.



Performance



Now for the most important question: does preloading really improve performance?



Of course! Ben Morel shared the results of comparative testing, which can be found in the same topic on composer , which we referred to above.



And also, that is interesting. If you wish, you can preload only the so-called hot classes



- classes that are often used in your code base. Ben Morel's tests show that loading only about 100 of these classes provides a higher performance increase than preloading everything at once. In the first case, productivity increases by 17%, in the second - by 13%.



Of course, the choice of classes for preloading depends on the specific project. It’s wise to start by simply preloading as much as possible. If these few percent differences in performance are so important to you, you will have to control the code at runtime.



All these operations, of course, can be automated, and this is likely to be done in the future.



Now it’s important that pre-load support will be added to composer



, which eliminates the need to create files for it yourself. This feature is very easy to configure on the server, provided that it is at your complete disposal.






Will you use preloading in the new version of PHP 7.4? Any thoughts or comments? Email me on Twitter or Email .



Traditionally, we are waiting for your comments and advantages if you find the article interesting :-)



All Articles