【问题标题】:Creating symfony command extending controller创建 symfony 命令扩展控制器
【发布时间】:2019-08-19 10:55:03
【问题描述】:

我正在编写一个 symfony 控制台命令,它可以通过使用“php bin/console app:mycommand”来执行(symfony 文档:https://symfony.com/doc/current/console.html#creating-a-command)。

在我的 MyCommand 类中,我需要使用 getDoctrine 函数,所以我必须扩展控制器,但我看不到如何做到这一点。有什么想法吗?

目前我在 CLI 上收到以下错误:尝试调用类“App\Command\MyCommand”的名为“getDoctrine”的未定义方法。

<?php
  // src/Command/MyCommand.php
  namespace App\Command;

  use Symfony\Component\Console\Command\Command;
  use Symfony\Component\Console\Input\InputInterface;
  use Symfony\Component\Console\Output\OutputInterface;

  use Symfony\Bundle\FrameworkBundle\Controller\Controller;

  class MyCommand extends Command
  {
    // the name of the command (the part after "bin/console")
    protected static $defaultName = 'app:mycommand';

    protected function configure()
    {

    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
      // Not working, producing mentioned error 
      $em = $this->getDoctrine()->getManager();
    }
  }
?>

【问题讨论】:

  • 您为什么希望能够调用该函数?是什么让您认为您“必须扩展控制器”?

标签: php shell symfony


【解决方案1】:

getDoctrine() 方法由ControllerTrait 提供,而ControllerTrait 又依赖于ContainerAwareTrait 进行容器注入。但是,这将提取您在命令中不需要的其他服务和方法,因此建议的方法是只注入您需要的服务,而不是注入整个容器,在这种情况下是 ObjectManager (@987654326 @是ORM和ODM共同实现的接口,如果两者都用或者只关心ORM,可以用Doctrine\ORM\EntityManagerInterface代替。

  <?php
  // src/Command/MyCommand.php
  namespace App\Command;

  use Symfony\Component\Console\Command\Command;
  use Symfony\Component\Console\Input\InputInterface;
  use Symfony\Component\Console\Output\OutputInterface;

  use Doctrine\Common\Persistence\ObjectManager;

  class MyCommand extends Command
  {
    // the name of the command (the part after "bin/console")
    protected static $defaultName = 'app:mycommand';

    private $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // Now you have access to the manager methods in $this->manager
        $repository = $this->manager->getRepository(/*...*/);
    }
  }

【讨论】:

  • 感谢您的帮助!但是现在我在执行时遇到了这个错误。为什么会这样? ObjectManager 被导入。 Cannot autowire service "debug.argument_resolver.not_tagged_controller.inner": argument "$manager" of method "__construct()" has type "Doctrine\Persistence\ObjectManager" but this class was not found.
  • @Ccenter 抱歉,我忘记了命名空间组件。希望它现在可以工作
  • 两个命名空间都在使用中,上述错误消失了。但是我收到$em = $this-&gt;manager-&gt;getDoctrine()-&gt;getManager(); 的以下运行时错误:Attempted to call an undefined method named "getDoctrine" of class "Doctrine\ORM\EntityManager". 缺少什么?我想明白这一点。除此之外:我在这里找到了一个可行的解决方案:stackoverflow.com/questions/48234418/…
  • @Ccenter 你不需要打电话给getDoctrine()-&gt;getManager()$this-&gt;manager已经是EntityManager了,你可以直接打电话给getRepository()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
相关资源
最近更新 更多