在PHP 7.4中预加载

本文的翻译是专门为Backend PHP Developer课程的学生准备的。



PHP 7.4添加了预加载功能,该功能可以显着提高代码性能。

简而言之,预紧力。

  • 要预加载文件,您需要编写一个单独的PHP脚本。
  • 该脚本在服务器启动时执行一次。
  • 所有预加载的文件都可以在内存中用于所有请求。
  • 在重新启动服务器之前,对源文件所做的更改将不起作用。

让我们更详细地讨论新功能。


不只是Opcache


是的,预加载基于opcache,但并非完全相同。 Opcache提取PHP源文件,将它们编译为操作码,然后将编译后的文件保存到磁盘。

操作码可以看作是代码的低级表示,可以在运行时轻松解释。 因此,opcache允许您跳过在运行时将源文件转换为PHP解释器实际需要的阶段。 明显节省!

但是,您可以节省更多。 用opcash文件编译的文件对其他文件一无所知。 如果您拥有类A(它是类B的扩展),则它们仍需要在运行时进行链接。 另外,opcache会检查源文件是否已更改,并且在检测到更改后会使它们的缓存无效。

而这里的预载可以解决:它不仅将源文件编译为操作码,而且还链接了相关的类,特征和接口。 它在内存中存储可执行代码(即PHP解释程序可以使用的代码)的“已编译”片段。

当请求到达服务器时,它可以使用已经加载到内存中的部分代码库,而无需花费额外的时间。

我们在说什么“代码库的一部分”?


练习预加载


为了正确进行预加载,开发人员必须告知服务器要下载哪些文件。 这是使用简单的PHP脚本完成的,因此无需担心。

没什么复杂的。

  • 您提供了一个预加载脚本,并使用opcache.preload在您的php.ini文件中链接了该脚本。
  • 您要预加载的每个PHP文件都必须从预加载脚本传递到opcache_compile_file()

假设您要预加载某种框架。 让它成为Laravel。 在这种情况下,您的脚本应查看vendor/laravel中的所有PHP文件,并一次添加一个。

这是如何在php.ini中包含此脚本:

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


这是一个示例实现:

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

可以使用include代替opcache_compile_file 。 但是,这里似乎存在一个错误 ,因为在编写第二个选项时不起作用。

警告您不能预加载不相关的类


有警告不能预加载未链接的类 ? 事实是,在预加载文件之前,您还需要预加载它们的依赖对象-接口,特征和父类。

如果在类依赖方面遇到任何问题,则在启动服务器时会警告您:

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

请注意, opcache_compile_file()opcache_compile_file()文件,但不会执行该文件。 这意味着,如果类具有尚未预加载的依赖项,则该类本身无法被预加载。

这并不重要:服务器将照常运行,但是您不会拥有要预加载的所有文件。

这就是为什么您需要仔细选择要预加载的文件以避免依赖问题的原因。 手动执行此任务是一项不愉快且耗时的任务,因此开发人员已在研究自动化解决方案。

作曲家支持


作曲者开发人员正在准备最有前途的自动化解决方案,该解决方案已在大多数现代PHP项目中使用。

现在,这些家伙正在研究在composer.json配置预加载的能力,该预加载反过来将代替您生成预加载文件。 与预加载本身一样,此功能仍在开发中。 您可以在此处关注事件的发展。
幸运的是,如果您不需要这样做,则不必手动配置预加载文件-作曲家可以为您完成此任务。

服务器要求


开发人员在使用预加载时还应牢记其他两个重要方面。

您已经知道您需要在php.ini创建一个条目才能使预加载起作用。 这意味着,如果您使用共享托管,则将无法根据需要配置PHP。

实际上,您将需要一个专用(虚拟)服务器来优化单个项目的预加载文件。 请记住这一点。

还要记住,每次要在内存中重新加载文件时,都需要重新启动服务器(如果使用php-fpm ,就足够了)。 对于大多数人来说,这是显而易见的,但是回想起来并不是多余的。

性能表现


现在是最重要的问题:预加载真的可以提高性能吗?

当然可以! Ben Morel分享了比较测试的结果,可以在我们上面提到的composer的同一主题中找到。

而且,这很有趣。 如果愿意,您可以仅预加载所谓的hot classes -代码库中经常使用的类。 Ben Morel的测试表明,与一次预加载所有类相比,仅加载这些类中的大约100种可提供更高的性能提升。 在第一种情况下,生产率提高了17%,在第二种情况下提高了13%。

当然,用于预加载的类的选择取决于特定的项目。 最合理的启动方法是尽可能简单地预加载。 如果这些性能上的少量差异对您如此重要,那么您将必须在运行时控制代码。

当然,所有这些操作都可以自动化,并且将来可能会完成。

现在,重要的是要在composer添加预加载支持,这样就无需自己为其创建文件。 如果您可以完全使用此功能,则在服务器上对其进行配置非常容易。



您将在新版本的PHP 7.4中使用预加载吗? 有什么想法或意见吗? 在TwitterEmail上给我发电子邮件

传统上,如果您发现本文有趣,我们将等待您的评论和优势:-)

Source: https://habr.com/ru/post/zh-CN463117/


All Articles