Doctrine standalone without cli-config.php

前端 未结 1 1084
后悔当初
后悔当初 2021-02-06 16:00

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 dire

相关标签:
1条回答
  • 2021-02-06 16:11

    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)

    0 讨论(0)
提交回复
热议问题