前言
PHP 7.4增加了预加载支持,这一功能可以显着提高代码的性能。
这是一个简单的预加载:
- 为了预加载文件,您需要编写自定义PHP脚本
- 此脚本在服务器启动时执行一次
- 所有预加载的文件都可在内存中用于所有请求
- 在重新启动服务器之前,对源文件所做的更改不会产生任何影响
让我们深入研究一下。
Opcache,但更多
虽然预加载是在顶级操作opcache上构建的,但它并不完全相同。Opcache将获取您的PHP源文件,将其编译为“操作码”,并将这些编译后的文件存储在磁盘上。
您可以将“操作码”视为代码的低级表示,可以在运行时轻松解释。因此,opcache会跳过源文件之间的转换步骤以及PHP解释器在运行时实际需要的内容。一场巨大的胜利!
但是,还有更多的东西可以获得。Opcached文件不了解其他文件。如果你有一个A从类扩展的类B,你仍然需要在运行时将它们链接在一起。此外,opcache执行检查以查看源文件是否已被修改,并将基于此文件使其缓存无效。
所以这就是预加载发挥作用的地方:它不仅将源文件编译为操作码,还将相关的类,特征和接口链接在一起。然后,它将保留这个“已编译”的可运行代码blob - 即:PHP解释器可用的代码 - 在内存中。
当请求到达服务器时,它现在可以使用已经加载到内存中的部分代码库,而没有任何开销。
那么,我们谈论的是“代码库的哪些部分”?
在实践中预加载
为了使预加载工作,开发人员必须告诉服务器要加载哪些文件。这是通过一个简单的PHP脚本完成的,所以没有什么可怕的。
规则很简单:
- 您提供了一个预加载脚本,并使用您的php.ini文件链接到它 opcache.preload
- 您要预加载的每个PHP文件都应该opcache_compile_file()从preload脚本中传递到
假设您想要预加载一个框架,例如Laravel。您的脚本必须遍历目录中的所有PHP文件vendor/laravel,并逐个包含它们。
以下是您在php.ini中链接到此脚本的方法:
opcache.preload=/path/to/project/preload.php
这是一个虚拟实现:
$files = /* An array of files you want to preload */; foreach ($files as $file) { opcache_compile_file($file); }
请注意opcache_compile_file,您也可以使用include该文件代替使用。虽然似乎有一个bug,因为在编写时这似乎不起作用。
警告:无法预加载未链接的类