Introduction to PHP 7.4 Preload
Tags: webdev, php, preload, opcache
Published: 2019-08-10 18:16:02

---
title: Introduction to PHP 7.4 Preload
published: true
description: Using opcache preload in PHP 7.4
tags: webdev, php, preload, opcache
canonical_url: https://andrewdavis.me/post/introduction-to-php-7-4-preload/
---
PHP 7.4 is the latest version of the PHP programming language that will launch later this year. PHP 7.4 recently went into beta, so I started exploring the new features. One feature showing a lot of promise is called [Opcache Preload](https://wiki.php.net/rfc/preload). Using preload you can set PHP to load certain PHP files into memory on startup. Doing so reduces the amount of files PHP has to compile when receiving an HTTP request which improves performance. Before exploring preload, let us look at how opcache works in the PHP runtime.

## Opcache Is Your Friend
In PHP, the term PHP is used for the programming language. However, the runtime that executes PHP code is called the Zend Engine. When the Zend Engine receives a request for a PHP file, it actually compiles the PHP file into a list of operation codes, hence the term `opcode`. The `opcache` Zend Engine extension stores those opcodes in memory after a PHP file is compiled, so that the PHP file does not have to be compiled again in subsequent requests for the file.

The `opcache.preload` directive allows a PHP programmer to instruct the opcache to cache the opcodes for a set of PHP files when the Zend Engine is activated. The preload option should be pointed to a PHP file that runs the function [`opcache_compile_file`](https://www.php.net/manual/en/function.opcache-compile-file.php) on the files you want preloaded.

## Enabling Preload
To test preloading, I set up an [example project](https://github.com/restoreddev/preloading-example) that uses [Slim 3](http://www.slimframework.com/docs/v3/) for routing.

To use preloading, you have to install PHP 7.4. I am using Ubuntu WSL on Windows with the [ondrej/php](https://launchpad.net/~ondrej/+archive/ubuntu/php) PPA activated. Since I'm using Ondrej's PPA, I can run `sudo apt install php7.4-fpm` in bash to get the latest 7.4 beta on my system. I use the FPM installation with Nginx as my web server and a host entry called `preloading.local` pointed at my project. After installation, I opened the FPM php.ini file (located at `/etc/php/7.4/fpm/php.ini` on my system) and changed the `opcache.preload` option to the path to my `preload.php` file in my project.

The `preload.php` file uses a modified `preload` function based on Dmitry Stogov's example in the [Preload RFC](https://wiki.php.net/rfc/preload). I have all the Slim dependencies loaded in a `vendor` folder using Composer. I then use the `preload` function in my `preload.php` on all the Composer source files I need to run the Slim application. After restarting PHP FPM (`sudo service php7.4-fpm restart`), I can open `preloading.local` in my browser and see my application run successfully.

## My Thoughts on Preload
1. I like that I did not have to use the Composer autoloader for my framework. Since all of the framework code was preloaded, autoloading is unnecessary. I do hope that Composer will generate an automatic `preload.php` file, like the `autoload.php` file, so that vendor dependencies can be preloaded easily.
2. The performance gain is miniscule for a small project like this one, however, I can see preloading being a great way to speed up large frameworks like Symfony, Laravel and especially Magento.
3. Preloading will be tricky to implement if you have multiple PHP projects on the same server, since you can only set one file to be preloaded.
4. I had an issue where preloading would not load the `functions.php` file in the `nikic/fast-route` module because it was wrapped in an `if` statement. I had to set up a patch file to manually load those functions without the `if` statement. It is probably because 7.4 is still in beta or my `preload.php` needs to be improved.
5. I do not think many PHP developers will use preload in development environments. I generally am reluctant to use features in production that are unused in dev because of the potential for unseen issues to arise on production servers. However, the risk is pretty low for preloading, so it will still be worth it to have it enabled.

All in all, I'm really looking forward to the performance gains from preloading. PHP is already one of the fastest scripting languages on the web and I am happy that the core team continues to push PHP into faster territories.

Next, I want to try [arrow functions](https://wiki.php.net/rfc/arrow_functions_v2), the [foreign function interface](https://wiki.php.net/rfc/ffi) and [typed properties](https://wiki.php.net/rfc/typed_properties_v2). There are a lot of great features being added to PHP soon!