预加载PHP脚本时,“未知类型依赖项”是什么意思?

时间:2019-12-29 15:01:24

标签: php preloading php-7.4

我正在尝试使用自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\MathBrick\Money的维护者,因此,如果需要对它们进行修改以使其可预加载,我将不知所措!

1 个答案:

答案 0 :(得分:0)

这意味着PHP在运行时无法在预加载的文件中找到类。 This only happens when there might be methods that are incompatible

  

预加载:放宽已知类型限制
  检查是否存在具有相同名称的父/接口/特征方法,然后才要求知道该类型。这样可以减少实际触发的次数。

预加载的文件不使用Composer自动加载器,因此不存在无法预加载的类。

Symfony通过creating a Preloader class修复了此问题,可以加载其依赖项。这是how to use it来预加载LoaderInterfaceAnnotationClassLoder

<?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()进行预加载。这样可以很好地处理循环依赖关系,但是如果预加载失败(而不只是警告),则将出现硬错误。