1

我在独立的 noframework 应用程序中使用带有Gedmo 扩展的 Doctrine。自动加载是通过 composer, composer.json 内容完成的:

{
  "autoload": {
    "psr-0": {
      "App": "src"
    }
  },
  "require": {
    "doctrine/orm": "^2.5",
    "gedmo/doctrine-extensions": "^2.4"
  }
}

App 核心类放在 /src 目录,composer 文件放在 /vendor 是通过工厂配置的 Doctrine,其主要代码如下:

<?php

namespace App\Factory;

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Common\Cache\FileCache;
use Doctrine\Common\EventManager;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;

class DoctrineFactory implements FactoryInterface
{
    /**
     * @param ContainerInterface $c
     * @return mixed
     */
    public function __invoke(ContainerInterface $c)
    {
        // Set up caches
        $cache = new FileCache('runtime/cache/doctrine');

        // Annotation reader
        $annotationReader = new AnnotationReader;
        $cachedAnnotationReader = new CachedReader($annotationReader, $cache);
        AnnotationRegistry::registerLoader(array(require 'vendor/autoload.php', 'loadClass'));

        // Add Gedmo extensions
        $driverChain = new MappingDriverChain();
        \Gedmo\DoctrineExtensions::registerAbstractMappingIntoDriverChainORM($driverChain, $cachedAnnotationReader);

        // Set up driver to read annotations from entities
        $annotationDriver = new AnnotationDriver($cachedAnnotationReader, 'src'));
        $driverChain->addDriver($annotationDriver, 'App\Entity');

        // General doctrine configuration
        $doctrineConfig = new Configuration;
        $doctrineConfig->setProxyDir(sys_get_temp_dir()));
        $doctrineConfig->setProxyNamespace('App\Entity\Proxy');
        $doctrineConfig->setAutoGenerateProxyClasses(false);
        $doctrineConfig->setMetadataDriverImpl($driverChain);
        $doctrineConfig->setMetadataCacheImpl($cache);
        $doctrineConfig->setQueryCacheImpl($cache);

        // Event manager to hook extensions
        $evm = new EventManager();

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

        // Create EntityManager
        // $config['conn'] is connection credentials  
        return EntityManager::create($config['conn'], $doctrineConfig, $evm);
    }
}

我的实体是:

<?php

namespace App\Entity;

use \Doctrine\ORM\Mapping as ORM;
use \Gedmo\Mapping\Annotation as Gedmo;

/**
 * Class ProductCategory2
 * @package App\Entity
 *
 * @Gedmo\Tree(type="nested")
 * @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
 */
class ProductCategory2
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=50)
     */
    private $name;

    /**
     * @Gedmo\TreeLeft
     * @ORM\Column(type="integer")
     */
    private $lft;

    /**
     * @Gedmo\TreeLevel
     * @ORM\Column(type="integer")
     */
    private $lvl;

    /**
     * @Gedmo\TreeRight
     * @ORM\Column(type="integer")
     */
    private $rgt;

    /**
     * @Gedmo\TreeRoot
     * @ORM\Column(type="integer", nullable=true)
     * @var
     */
    private $root;

    /**
     * @Gedmo\TreeParent
     * @ORM\ManyToOne(targetEntity="ProductCategory2", inversedBy="children")
     */
    private $parent;
}

我的 cli-config.php 配置正确。我运行学说 cli 工具通过命令生成实体样板代码:

“供应商/bin/doctrine” orm:generate-entities src

它回答我:

处理实体“Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonal\Translation”</p>

处理实体“Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation”</p>

处理实体“Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry”</p>

处理实体“Gedmo\Tree\Entity\MappedSuperclass\AbstractClosure”</p>

处理实体“App\Entity\ProductCategory2”</p>

实体工作正常,但命令将额外文件添加到我的 src 文件夹中:

src\Gedmo
├───Loggable
│   └───Entity
│       └───MappedSuperclass/AbstractLogEntry.php
├───Translatable
│   └───Entity
│       └───MappedSuperclass/AbstractTranslation.php
└───Tree
    └───Entity
        └───MappedSuperclass/AbstractClosure.php

如果我通过上述命令再次生成实体,则会出错。

PHP 致命错误:无法在第 9 行的 \src\Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry.php 中重新声明类 Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry

要修复它,我需要<ROOT>/src/Gedmo先删除目录。

任何人都可以帮助找到配置中的错误以防止出现这个烦人的额外文件吗?

感谢帮助

4

1 回答 1

0

在学说 generate-entities 命令之后,我添加了 hack 以清除烦人的目录。cli-config.php 的完整列表如下:

<?php

use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Interop\Container\ContainerInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;

require "vendor/autoload.php";

/** @var ContainerInterface $container */
$container = require 'app/bootstrap.php';

$dispatcher = new EventDispatcher();
// Post terminate cli command listener
$dispatcher->addListener(ConsoleEvents::TERMINATE, function(ConsoleTerminateEvent $event) {
    $commandName = $event->getCommand()->getName();
    switch($commandName) {
        case 'orm:generate-entities':
            // clear /src/Gedmo dir
            \App\Utils\FilesystemUtils::removeDir('src/Gedmo');
            break;
    }
});

// Create doctrine cli environment via helper
$helperSet = ConsoleRunner::createHelperSet($container->get(\Doctrine\ORM\EntityManager::class));

// Wrap it into Symfony Console App and add some extra commands
$app = new Application('Doctrine Command Line Interface', \Doctrine\ORM\Version::VERSION);
$app->setDispatcher($dispatcher);
$app->setCatchExceptions(true);
$app->setHelperSet($helperSet);
// add default commands
ConsoleRunner::addCommands($app);
// here you may add extra commadts via $app->add(..)
$app->run();

官方文档:

  1. 如何将教义 cli 命令包装到 symfony 控制台应用程序中

  2. 如何将事件系统注入 symfony 控制台应用程序

于 2016-01-24T04:53:18.743 回答