本文介绍了当我打开php opcache时,教义就会被吓倒了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Doctrine和中有一个非常奇怪的问题,PHP 5.5.6 Opcache 。当 opcache 模块关闭时,一切正常工作。一旦我打开它,我开始得到以下异常:

I'm having a really strange problem with Doctrine and PHP 5.5.6 Opcache. Everything is working just fine when the opcache module is turned off. Once I turn it on, I begin getting the following exception:

Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'Class "Admin\Models\Users\Role" is not a valid entity or mapped super class.' in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php on line 336
( ! ) Doctrine\ORM\Mapping\MappingException: Class "Admin\Models\Users\Role" is not a valid entity or mapped super class. in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php on line 336
Call Stack
#   Time    Memory  Function    Location
1   0.0000  128016  {main}( )   ../app.php:0
2   0.0185  615020  Core\Bootstrap->handle( )   ../app.php:53
3   0.0210  695744  call_user_func_array ( )    ../Bootstrap.php:111
4   0.0210  695976  Admin\Controllers\DashboardController->indexAction( )   ../Bootstrap.php:111
5   0.0210  696028  Doctrine\ORM\EntityManager->getRepository( )    ../DashboardController.php:25
6   0.0210  696072  Doctrine\ORM\Repository\DefaultRepositoryFactory->getRepository( )  ../EntityManager.php:759
7   0.0210  696176  Doctrine\ORM\Repository\DefaultRepositoryFactory->createRepository( )   ../DefaultRepositoryFactory.php:50
8   0.0210  696200  Doctrine\ORM\EntityManager->getClassMetadata( ) ../DefaultRepositoryFactory.php:67
9   0.0210  696420  Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor( ) ../EntityManager.php:295
10  0.0213  699628  Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata( )   ../AbstractClassMetadataFactory.php:211
11  0.0224  781128  Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata( )    ../AbstractClassMetadataFactory.php:318
12  0.0224  782824  Doctrine\ORM\Mapping\Driver\AnnotationDriver->loadMetadataForClass( )   ../ClassMetadataFactory.php:117

我相信我的实体是正确定义的 - 正如我刚才提到的,一旦我禁用了opcache,一切都按预期工作。要初始化Doctrine我正在使用这段代码:

I believe my entities are defined properly - as I mentioned in the beginning, once I disable opcache everything works as expected. To initialize Doctrine I'm using this piece of code:

// $this->getEntityPaths()   returns an array of existing absolute paths, each of which is checked with realpath().
// $this->getProxyPath()     returns a string with the absolute path, checked with realpath()
// $this->getInDevelopment() returns boolean and is set to TRUE


$config = Setup::createAnnotationMetadataConfiguration($this->getEntityPaths(), $this->getInDevelopment(), $this->getProxyPath());
$config->setAutoGenerateProxyClasses(true);

$dbParams = array(
    'driver'   => 'pdo_pgsql',
    'host'     => $this->getHost(),
    'port'     => $this->getPort(),
    'user'     => $this->getUser(),
    'password' => $this->getPass(),
    'dbname'   => $this->getName()
);

$this->db = EntityManager::create($dbParams, $config);

我也尝试过这样的配置:

I've also tried this configuration:

$config = new Configuration;
$config->setProxyDir($this->getProxyPath());
$config->setProxyNamespace('DoctrineProxies');
$config->setAutoGenerateProxyClasses(true);

$driverImpl = $config->newDefaultAnnotationDriver($this->getEntityPaths());

$config->setMetadataDriverImpl($driverImpl);
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache());
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache());

// the connection configuration
$dbParams = array(
    'driver'   => 'pdo_pgsql',
    'host'     => $this->host,
    'port'     => $this->port,
    'user'     => $this->user,
    'password' => $this->pass,
    'dbname'   => $this->name
);

$this->db = EntityManager::create($dbParams, $config);

这是实体

/**
 * Roles
 *
 * @Table(name="roles")
 * @Entity
 */
class Role
{
    /**
     * @Id
     * @Column(name="role_id", type="integer", nullable=false)
     * @GeneratedValue(strategy="IDENTITY")
     */
    private $role_id;


    /**
     * @Column(name="name", type="string", length=100, nullable=false)
     */
    private $name;
}

为了简单起见,我有 AutoGenerateProxyClasses ,但只是为了确保我也通过生成代理测试它。不幸的是我得到了同样的例外。我不知道如何追求这个问题,究竟是什么问题。这是一个教义错误吗?为什么开始 OpCache 导致 Doctrine 异常并使其失效?我错过了配置部分或实体中的某些东西?

For the sake of simplicity I have AutoGenerateProxyClasses on, but just to be sure I've also tested it by generating the proxies. Unfortunately I get the same exception. I'm not sure how to pursue this problem and what exactly IS the problem. Is it a Doctrine bug? Why having OpCache turned on results in Doctrine exceptions and having it off works fine? Have I missed something in the configuration part or the entity?

推荐答案

经过大量的调试,我终于明白了解原则在OpCache上设置不正常。显然默认情况下,opcache不会存储或加载您在php文件中的任何注释。您可以想像,这导致任何依赖于注释的PHP库中出现大量无法解释的异常。所以只需去你的 php.ini ,更改下面的行,你会和新的一样好。我想这应该进入教义的帮助。

After a lot of debugging, I finally managed to understand why Doctrine was not working right with OpCache set on. Apparently by default opcache does not store or load any comments you have in your php file. As you can imagine, this results in tons of unexplained exceptions in any php library which relies on Annotations. So just go to your php.ini, change the lines below and you'll be as good as new. I guess this should go into the Doctrine help as well.

opcache.save_comments=1
opcache.load_comments=1

这篇关于当我打开php opcache时,教义就会被吓倒了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 08:19