问题
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
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);
Here is the entity
/**
* 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;
}
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?
回答1:
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
来源:https://stackoverflow.com/questions/21925354/doctrine-is-freaking-out-when-i-turn-on-php-opcache-on