4

我想将 Doctrine ORM 集成到我的(非 Symfony)项目中。我已经在另一个项目中完成了这项工作,并cli-config.php在项目根目录中使用了著名的。

但是现在,在我的新项目中,我使用 Symfony Console 组件和 Dependency Injection 组件(通过标记来引用服务和命令)。

1.我绝对不想cli-config.php在项目根目录中有一个。Sf Doctrine Bundle 如何做到这一点?

2.另外(但不太重要),我想将 Doctrine 命令放入我的项目 CLI 中。最好的方法是什么?在我的services.yml? 或者创建通过 PHP 调用 Doctrine 命令的本地“装饰器命令”?

4

1 回答 1

4

最后,经过一些谷歌搜索和实验,我找到了一个完整的解决方案。

只需阅读 中的教义.php vendor/binconfig-cli.php避免硬编码文件很容易。

1.创建实体管理器

就我而言,我使用工厂,这种方法可以为doctrine.em服务提供水分。

$config特定于我的应用程序,更改值以使用您自己的逻辑。)

use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

public function createEntityManager()
{
    $config = $this->get('config');

    $metadataConfig = Setup::createAnnotationMetadataConfiguration(
        [$config->meta('app_path') . '/Entity'],
        $config->oc->doctrine->dev_mode
    );

    return EntityManager::create((array) $config->oc->doctrine->connection, $metadataConfig);
}

2. 在你的 CLI 命令中合并 Doctrine CLI 命令

Somewe 在您的代码中,例如在 some 中bootstrap.php,您可能会声明您的Symfony\Component\Console\Application命令行界面,这就是我这样做的方式(foreach只需添加在我的services.yml文件中定义的命令):

$application = new Application('MyApp CLI', '0.0.1');

$services = $container->findTaggedServiceIds('oc.command');

foreach(array_keys($services) as $serviceId)
{
    $application->add($container->get($serviceId));
}

$application->run();

现在,我们只需要求 Doctrine 将其命令注入我们的应用程序:

$application = new Application('MyApp CLI', '0.0.1');

$helperSet = ConsoleRunner::createHelperSet($container->get('doctrine.em'));
$application->setHelperSet($helperSet);

ConsoleRunner::addCommands($application);

$services = $container->findTaggedServiceIds('oc.command');

foreach(array_keys($services) as $serviceId)
{
    $application->add($container->get($serviceId));
}

$application->run();

就是这样!您还可以使用arsfeld 在此 GitHub 问题上的回答来仅添加 Doctrine 命令的子集。

3.奖励:只导入需要的命令并重命名它们

您可以创建继承 Doctrine 命令的装饰器命令(这对于重新定义 Doctrine 命令的名称很有用,就像 Symfony Doctrine Bundle 所做的那样,例如orm:validate-schema-> doctrine:schema:validate)。

为此,请删除ConsoleRunner::addCommands($application);我们在步骤 2 中添加的行。对于您要重新定义的每个命令,您需要在您的应用程序中创建一个注册新命令。此命令将“ extends”目标 Doctrine 命令并将覆盖该configure()方法。

这是一个例子orm:validate-schema

<?php

namespace MyApp\Command\Doctrine;

use Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand;

class SchemaValidateCommand extends ValidateSchemaCommand
{
    protected function configure()
    {
        parent::configure();
        $this->setName('doctrine:schema:validate');
    }
}

一些 Doctrine 命令的别名会污染你的命令命名空间,比如orm:generate-entitiesorm:generate:entities。要删除这些别名,请在configure()中添加->setAliases(array())

$this->setName('doctrine:generate:entities')->setAliases([]);

恭喜,你刚刚重做了 Symfony Doctrine Bundle :p (jk)

于 2015-02-07T18:25:40.500 回答