Doctrine standalone without cli-config.php

对着背影说爱祢 提交于 2019-12-21 02:50:06

问题


I want to integrate Doctrine ORM into my (non-Symfony) project. I already done this in another project and used the famous cli-config.php into the project root directory.

But now, in my new project, I use the Symfony Console component and the Dependency Injection component (to reference services and commands, by tagging them).

1. I absolutely don't want to have a cli-config.php in the project root. How the Sf Doctrine Bundle do this?

2. Also (but it is less important), I would like to have the Doctrine commands into my project CLI. What would be the best way to do this? Create references to Doctrine commands into my services.yml ? Or create local "decorator commands" that call Doctrine commands via PHP?


回答1:


Finally, after some googling and experiments, I found a complete solution.

Just read the doctrine.php in vendor/bin. It is very easy to avoid the hardcoded config-cli.php file.

1. Create an entity manager

In my case, I use a factory and this method hydrates the doctrine.em service.

($config is specific to my app, change values to use your own logic.)

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. Merge Doctrine CLI commands in your CLI commands

Somewere in your code, like in some bootstrap.php, you probably declare your Symfony\Component\Console\Application command line interface, that's how I do this (the foreach simply adds commands defined in my services.yml file):

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

Now, we simply ask Doctrine to inject its commands into our Application:

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

That's it! You can also only add a subset of the Doctrine commands by using arsfeld's answer on this GitHub issue.

3. Bonus: only import needed commands and rename them

You can create decorator commands that inherit Doctrine commands (this is useful to redefine the name of Doctrine commands, as Symfony Doctrine Bundle does, eg. orm:validate-schema -> doctrine:schema:validate).

To do this, remove the line ConsoleRunner::addCommands($application); we added in step 2. For each command you want to redefine, you will need to create an register a new command in your app. This command will "extends" the target Doctrine command and will override the configure() method.

Here is an example with 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');
    }
}

Some Doctrine commands have aliases that will pollute your command namespaces, like orm:generate-entities and orm:generate:entities. To remove these aliases, in configure(), add ->setAliases(array()).

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

Congratulations, you just redone the Symfony Doctrine Bundle :p (jk)



来源:https://stackoverflow.com/questions/28384739/doctrine-standalone-without-cli-config-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!