5

我想在我的 Zend Framework-Application 中结合使用 Doctrine 2 和“l3pp4rd/DoctrineExtensions”。但我只收到以下错误消息:

Entities\USER_User 类中的注释“@Doctrine\ORM\Mapping\Entity”不存在,或者无法自动加载。

应用程序\bootstrap.php

  protected function _initDoctrine() {

    require_once('Doctrine/Common/ClassLoader.php');
    $autoloader = Zend_Loader_Autoloader::getInstance();

    $classLoader = array(new \Doctrine\Common\ClassLoader('Doctrine'), 'loadClass');
    $autoloader->pushAutoloader($classLoader, 'Doctrine\\');

    $classLoader = new \Doctrine\Common\ClassLoader('Entities',
      realpath(Zend_Registry::get('config')->resources->entityManager->connection->entities), 'loadClass');
    $autoloader->pushAutoloader(array($classLoader, 'loadClass'), 'Entities');

    $classLoader = new \Doctrine\Common\ClassLoader('Repositories',
      realpath(Zend_Registry::get('config')->resources->entityManager->connection->entities), 'loadClass');
    $autoloader->pushAutoloader(array($classLoader, 'loadClass'), 'Repositories');
  }

library\My\Resource\Entitymanager.php 位于http://www.gediminasm.org/article/annotation-reference

class My_Resource_Entitymanager extends Zend_Application_Resource_ResourceAbstract
{

    public function init()
    {

        // WARNING: setup, assumes that autoloaders are set
        // configuration settings from the application.ini file
        $zendConfig = new Zend_Config($this->getOptions());
        // globally used cache driver, in production use APC or memcached
        $cache = new Doctrine\Common\Cache\ArrayCache;
        // standard annotation reader
        $annotationReader = new Doctrine\Common\Annotations\AnnotationReader;
        $cachedAnnotationReader = new Doctrine\Common\Annotations\CachedReader(
            $annotationReader, // use reader
            $cache // and a cache driver
        );
        // create a driver chain for metadata reading
        $driverChain = new Doctrine\ORM\Mapping\Driver\DriverChain();
        // load superclass metadata mapping only, into driver chain
        // also registers Gedmo annotations.NOTE: you can personalize it
        Gedmo\DoctrineExtensions::registerAbstractMappingIntoDriverChainORM(
            $driverChain, // our metadata driver chain, to hook into
            $cachedAnnotationReader // our cached annotation reader
        );

        // now we want to register our application entities,
        // for that we need another metadata driver used for Entity namespace
        $annotationDriver = new Doctrine\ORM\Mapping\Driver\AnnotationDriver(
            $cachedAnnotationReader, // our cached annotation reader
            $zendConfig->connection->entities // paths to look in
        );
        // NOTE: driver for application Entity can be different, Yaml, Xml or whatever
        // register annotation driver for our application Entity namespace
        $driverChain->addDriver($annotationDriver, 'Entities');

        // general ORM configuration
        $config = new Doctrine\ORM\Configuration;
        $config->setProxyDir($zendConfig->connection->proxies->location);
        $config->setProxyNamespace($zendConfig->connection->proxies->ns);
        $config->setAutoGenerateProxyClasses($zendConfig->connection->proxies->generate); // this can be based on production config.
        // register metadata driver
        $config->setMetadataDriverImpl($driverChain);
        // use our allready initialized cache driver
        $config->setMetadataCacheImpl($cache);
        $config->setQueryCacheImpl($cache);

        // create event manager and hook prefered extension listeners
        $evm = new Doctrine\Common\EventManager();
        // gedmo extension listeners, remove which are not used

        // sluggable
        $sluggableListener = new Gedmo\Sluggable\SluggableListener;
        // you should set the used annotation reader to listener, to avoid creating new one for mapping drivers
        $sluggableListener->setAnnotationReader($cachedAnnotationReader);
        $evm->addEventSubscriber($sluggableListener);

        // tree
        $treeListener = new Gedmo\Tree\TreeListener;
        $treeListener->setAnnotationReader($cachedAnnotationReader);
        $evm->addEventSubscriber($treeListener);

        // loggable, not used in example
        $loggableListener = new Gedmo\Loggable\LoggableListener;
        $loggableListener->setAnnotationReader($cachedAnnotationReader);
        $evm->addEventSubscriber($loggableListener);

        // timestampable
        $timestampableListener = new Gedmo\Timestampable\TimestampableListener;
        $timestampableListener->setAnnotationReader($cachedAnnotationReader);
        $evm->addEventSubscriber($timestampableListener);

        // translatable
        $translatableListener = new Gedmo\Translatable\TranslatableListener;
        // current translation locale should be set from session or hook later into the listener
        // most important, before entity manager is flushed
        $translatableListener->setTranslatableLocale('en');
        $translatableListener->setDefaultLocale('en');
        $translatableListener->setAnnotationReader($cachedAnnotationReader);
        $evm->addEventSubscriber($translatableListener);

        // sortable, not used in example
        $sortableListener = new Gedmo\Sortable\SortableListener;
        $sortableListener->setAnnotationReader($cachedAnnotationReader);
        $evm->addEventSubscriber($sortableListener);

        // mysql set names UTF-8 if required
        $evm->addEventSubscriber(new Doctrine\DBAL\Event\Listeners\MysqlSessionInit());
        // DBAL connection
        $connection = array(
            'driver'   => "{$zendConfig->connection->driver}",
            'host'     => "{$zendConfig->connection->host}",
            'dbname'   => "{$zendConfig->connection->dbname}",
            'user'     => "{$zendConfig->connection->user}",
            'password' => "{$zendConfig->connection->password}"
        );
        // Finally, create entity manager
        $em = Doctrine\ORM\EntityManager::create($connection, $config, $evm);
        Zend_Registry::set('em', $em);
        return $em;

    }

}

应用程序\模型\USER_User.php

namespace Entities;

use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class USER_User
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * Retrieve user id
     */
    public function getId()
    {
        return $this->id;
    }
}

应用程序\配置\应用程序.ini

...
includePaths.library = APPLICATION_PATH "/../library/Doctrine"
...
pluginPaths.My_Resource = "My/Resource"
...
autoloaderNamespaces[] = "Doctrine"
autoloaderNamespaces[] = "Gedmo"
autoloaderNamespaces[] = "Symfony"
autoloaderNamespaces[] = "My"
...
resources.entityManager.connection.driver = "pdo_mysql"
resources.entityManager.connection.host = "localhost"
resources.entityManager.connection.dbname = "test"
resources.entityManager.connection.user = "test"
resources.entityManager.connection.password = "test"
resources.entityManager.connection.entities = APPLICATION_PATH "/models"
resources.entityManager.connection.proxies.location = APPLICATION_PATH "/models/Proxies"
resources.entityManager.connection.proxies.ns = "Proxies"

; According to Doctrine manual, this should be true for
; development, and false for production
resources.entityManager.connection.proxies.generate = true
...

有什么想法可以让这个工作吗?

4

3 回答 3

7

解决了这个问题的答案: doctrine2 autloader with cli must use AnnotationRegistry

添加到 library\My\Resource\Entitymanager.php

use Doctrine\Common\Annotations\AnnotationRegistry; 
class My_Resource_Entitymanager extends Zend_Application_Resource_ResourceAbstract
{

    public function init()
    {
        AnnotationRegistry::registerFile(__DIR__ . '/../../Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
        // WARNING: setup, assumes that autoloaders are set
        // configuration settings from the application.ini file
        ...

我也删了

$classLoader = array(new \Doctrine\Common\ClassLoader('Doctrine'), 'loadClass');
$autoloader->pushAutoloader($classLoader, 'Doctrine\\');

从应用程序\bootstrap.php

感谢您阅读我的问题!

于 2012-09-17T08:52:48.510 回答
2

我刚刚在 Zend Framework 2 上遇到了同样的问题,解决方案几乎相同。只需确保在应用程序设置期间执行上述语句。这可以在您的 Module.php 中轻松完成:

class Module
{
    // ...

    /**
     * Event being executed on bootstrap
     */
    public function onBootstrap(Event $e)
    {
        AnnotationRegistry::registerFile('path/to/ORM/Mapping/Driver/DoctrineAnnotations.php');
    }
}
于 2012-11-19T19:56:05.970 回答
2

以下代码段将使用您现有的自动加载器配置来查找实体类,而无需对任何路径进行硬编码。

use Doctrine\Common\Annotations\AnnotationRegistry;
AnnotationRegistry::registerLoader('class_exists');

这是 Zend Framework 2 的教条模块使用的方法,并且至少从 2.1 版开始就在 Doctrine 中。它适用于任何使用注释注册表的东西,包括像 PHPCR-ODM 这样的文档映射器。

这是教义模块中的用法:

https://github.com/doctrine/DoctrineModule/blob/1.1.0/src/DoctrineModule/Module.php#L54

于 2016-09-14T12:29:25.747 回答