我正在尝试使用自PHP 7.4起可用的新preloading feature。
我运行composer install --no-dev --optimize-autoloader
来生成项目中所有可用类的列表,并使用以下preload.php
脚本来预加载它们:
$files = require 'vendor/composer/autoload_classmap.php';
foreach (array_unique($files) as $file) {
opcache_compile_file($file);
}
并在我的opcache.ini
文件中配置此预加载脚本:
opcache.preload=/path/to/preload.php
并重新启动php-fpm
。现在systemctl status php-fpm.service
报告以下警告:
PHP警告:无法预加载未链接的类Brick \ Money \ Context \ CashContext:第16行上的...中的未知类型依赖项
PHP警告:无法预加载未链接的类Brick \ Money \ Context \ AutoContext:第17行上的...中的未知类型依赖项
PHP警告:无法预加载未链接的类Brick \ Math \ BigRational:第17行上的...中的未知类型依赖项
PHP警告:无法预加载未链接的类Brick \ Math \ BigInteger:第20行上的...中的未知类型依赖项
PHP警告:无法预加载未链接的类Brick \ Math \ BigDecimal:第15行上的...中的未知类型依赖项
“未知类型依赖项”是什么意思?如何预加载这些课程?
注意:我是有问题的库Brick\Math和Brick\Money的维护者,因此,如果需要对它们进行修改以使其可预加载,我将不知所措!
答案 0 :(得分:0)
这意味着PHP在运行时无法在预加载的文件中找到类。 This only happens when there might be methods that are incompatible:
预加载:放宽已知类型限制
检查是否存在具有相同名称的父/接口/特征方法,然后才要求知道该类型。这样可以减少实际触发的次数。
预加载的文件不使用Composer自动加载器,因此不存在无法预加载的类。
Symfony通过creating a Preloader
class修复了此问题,可以加载其依赖项。这是how to use it来预加载LoaderInterface
和AnnotationClassLoder
:
<?php
// preload.php
$classes[] = 'Symfony\Component\Config\Loader\LoaderInterface';
$classes[] = 'Symfony\Component\Routing\Loader\AnnotationClassLoader';
Preloader::preload($classes);
除非有更好的方法,否则您可以复制该类或预加载库依赖的所有类。
如果您可以将预加载失败视为硬错误,请使用answer from NikiC:
为避免依赖性问题,您可以使用
require
而不是opcache_compile_file()
进行预加载。这样可以很好地处理循环依赖关系,但是如果预加载失败(而不只是警告),则将出现硬错误。