2014-02-21 24 views
3

我對於Doctrine和PHP 5.5.6 Opcache有一個非常奇怪的問題。當opcache模塊關閉時,一切正常。當我打開它,我開始收到以下異常:當我打開php opcache的時候,學說很嚇人

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一切正常。要初始化學說我使用這段代碼:

// $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); 

我也試過這樣配置:

$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例外,並讓它關閉工作正常?我錯過了配置部分或實體中的某些內容嗎?

回答

7

經過大量調試之後,我終於理解了爲什麼Doctrine與OpCache無法正常工作。顯然默認情況下,opcache不會存儲或加載您在php文件中的任何註釋。正如你可以想象的那樣,這會導致任何php庫中依賴註解的大量無法解釋的異常。所以,只要去你的php.ini,改變下面的線條,你就會像新的一樣好。我想這也應該進入Doctrine的幫助。

opcache.save_comments=1 
opcache.load_comments=1 
+1

如果我在php.ini中添加這兩行,這個內置的opcache將用於doctrine2的目的還是我必須單獨安裝APCu?據我所知,opcache並不像APCu那樣是完整的緩存。 –

+0

這取決於你的情況 - 如果你正在使用的平臺流量很大,你可能想使用'Memcache'。否則,你應該可以只使用'Opcache' – tftd

+0

根據我的知識和教條文檔http://doctrine-orm.readthedocs.org/en/latest/reference/caching.html,我們只有以下驅動程序:1. $ cacheDriver = new \ Doctrine \ Common \ Cache \ ApcCache(); 2. $ cacheDriver = new \ Doctrine \ Common \ Cache \ MemcacheCache(); 3. $ cacheDriver = new \ Doctrine \ Common \ Cache \ MemcachedCache(); $ cacheDriver = new \ Doctrine \ Common \ Cache \ XcacheCache(); 4. $ cacheDriver = new \ Doctrine \ Common \ Cache \ RedisCache(); 5. $ cacheDriver = new \ Doctrine \ Common \ Cache \ ArrayCache();任何驅動程序都可以使用內置的opcache。 –