使用 Symfony 5.4 预加载 Opcache / PHP8 / Platform.sh

Opcache Preloading with Symfony 5.4 / PHP8 / Platform.sh

我试图在 PHP8 上 Platform.sh 上的 Symfony 5.4 运行 上设置 Opcache 预加载,运行 出现致命错误。

配置

包括必要的部分:

// platform.app.yaml
...
variables
  php
    'opcache.preload': 'var/cache/prod/App_KernelProdContainer.php'
...

hooks:
  build: |
    ...
    composer dump-autoload --no-dev --classmap-authoritative
  deploy: |
    ...
    sv restart app
...

我可以验证 App_KernelProdContainer.php 文件是在上面配置中定义的正确位置创建的:

<?php

// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.

if (\class_exists(\ContainerF9HiXre\App_KernelProdContainer::class, false)) {
    // no-op
} elseif (!include __DIR__.'/ContainerF9HiXre/App_KernelProdContainer.php') {
    touch(__DIR__.'/ContainerF9HiXre.legacy');

    return;
}

if (!\class_exists(App_KernelProdContainer::class, false)) {
    \class_alias(\ContainerF9HiXre\App_KernelProdContainer::class, App_KernelProdContainer::class, false);
}

return new \ContainerF9HiXre\App_KernelProdContainer([
    'container.build_hash' => 'F9HiXre',
    'container.build_id' => '98091d49',
    'container.build_time' => 1644501054,
], __DIR__.\DIRECTORY_SEPARATOR.'ContainerF9HiXre');

包含的文件 ContainerF9HiXre/App_KernelProdContainer.php 在 use 语句中抛出错误,如下所示:

Fatal error:  Uncaught Error: Class &quot;Symfony\Component\DependencyInjection\Container&quot; not found in /app/var/cache/prod/ContainerF9HiXre/App_KernelProdContainer.php:17
Stack trace:
#0 /app/var/cache/prod/App_KernelProdContainer.php(7): include()
#1 {main}
  thrown in /app/var/cache/prod/ContainerF9HiXre/App_KernelProdContainer.php on line 17

包含文件中的使用语句如下所示:

namespace ContainerF9HiXre;

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

您似乎使用了错误的预加载文件。

生成的文件的名称类似于 srcApp_KernelProdContainer.preload.php。但无论如何,您可能不应该将此文件直接添加到 opcache.preload,而是 Symfony 生成的 config/preload.php.

从 platform.sh the path is resolved relative to the project root 开始,您可以使用这样的相对路径:

opcache.preload=config/preload.php

如果您没有此文件(例如不完整的食谱),您可以通过 运行 composer recipes:update symfony/framework-bundle 简单地 re-generate 它,如 here.[=19 所述=]

或者,如果您没有使用 Symfony Flex 而想手动执行,您可以简单地从适当的配方中复制文件,like this one

无论如何这是一个非常简单的脚本:

<?php

if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
    require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
}