原则错误:“打开失败需要 '/tmp/__CG__Source.php'”

2022-08-30 13:22:19

我正在尝试将我的PHP应用程序迁移到Ubuntu服务器,但没有成功。任何帮助将不胜感激。

首先,我按照 Doctrine 入门手册的第一部分(直到“生成数据库模式”)将 Doctrine 成功安装到 /jorrit/myapp 中。其次,我将我的PHP脚本(使用教义)放在文件夹/jorrit/myapp中。

当我尝试在CLI中运行我的PHP脚本时,我收到以下错误消息:

PHP 警告: require(/tmp/__CG__Source.php): 无法打开流: 在 /jorrit/myapp/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php 200 行中没有这样的文件或目录

PHP 致命错误: require(): 打开失败所需的“/tmp/__CG__Source.php” (include_path='.:/usr/share/php:/usr/share/pear') in /jorrit/myapp/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php 第 200 行

Bootstrap.php看起来像这样:

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once "vendor/autoload.php";

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = false;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);

// the connection configuration
$dbParams = array(
        'driver'   => 'pdo_mysql',
        'host'     => 'xx',
        'user'     => 'xx',
        'password' => 'xx',
        'dbname'   => 'xx',
        'profiler' => 'false'
);


// obtaining the entity manager
$entityManager = EntityManager::create($dbParams, $config);

?>

我的 PHP 脚本的第一行:

<?php

require_once "bootstrap.php";
require_once 'classes.php';

$connection = $entityManager->getConnection();

该应用程序在我的开发环境(Windows)中工作正常。/tmp 文件夹存在且可访问。数据库成功迁移并存在。我没有更改供应商文件夹中的任何内容。

有什么想法吗?提前感谢您的帮助。


答案 1

TL;DR 您只需要手动生成代理类

vendor/bin/doctrine orm:generate-proxies

Doctrine使用代理来连接数据库。代理是从实体类生成的。

在开发模式下,它会在每个请求上生成一个代理,因为您可以对实体类进行更改。

在生产模式下,它不会每次都生成代理。出于性能原因,它假定代理存在并直接包含它们。

代理生成有几种模式:

  1. ALWAYS - 它生成代理,这是开发模式的默认设置
  2. 从不 - 它从不生成代理,这是生产模式的默认设置
  3. ON_DEMAND - 仅当代理文件不存在时,它才会生成代理。此选项的缺点是每次都必须调用file_exists(),这可能会导致性能问题。

现在命令

vendor/bin/doctrine orm:generate-proxies

生成 /tmp 的代理类。我会说这可能仍然会引起麻烦,因为服务器上的其他应用程序可能会意外删除这些文件。一种选择是您可以将 /tmp 目录访问权限更改为 1777

sudo chmod 1777 /tmp

777前面的尖头“1”意味着,虽然每个人都可以读/写到/tmp目录,但你只能对自己的文件进行操作。即,您无法删除其他用户创建的文件。

如需进一步阅读,请查看 http://docs.doctrine-project.org/en/latest/reference/advanced-configuration.html#auto-generating-proxy-classes-optional

您还可以将代理目录设置为其他位置,以便其他应用程序无法修改它们。http://docs.doctrine-project.org/en/latest/reference/advanced-configuration.html#autoloading-proxies


答案 2

在一行又一行的代码中,您可以尝试$config$config->setAutoGenerateProxyClasses(true);

但是CLI版本要好得多,因为它避免了在刷新时进行再生,就像在代码中可能无法避免的那样。

要更改缓存目录,您可以尝试:

$cacheDir = dirname(__FILE__).'/cache';
if (!is_dir($cacheDir)) {
    mkdir($cacheDir);
}


$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, $cacheDir);

推荐