使用Symfony 6中的EntityManagerInterface命令

huangapple go评论55阅读模式
英文:

Using EntityManagerInterface in command symfony 6

问题

I am trying to pass EntityManagerInterface to Command and it looks like the parent constructor only accepts string or null

#[AsCommand(
    name: 'app:cleanDB'      
)]
class CleanDBCommand extends Command
{

    private $em;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->em = $entityManager;

        parent::__construct($entityManager);
    }      

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $date = new \DateTime('now');
        $repo = $this->em->getRepository(User::class);
        $shortUrl = $repo->findBy(['createdAt'=>'<'.$date->format('Y-m-d')]);
        $io = new SymfonyStyle($input, $output);             
        $io->success('You have a new command! Now make it your own! Pass --help to see your options.');

        return Command::SUCCESS;
    }
}

I get the following error

Symfony\Component\Console\Command\Command::__construct(): Argument #1 ($name) must be of type ?string, Container6Yp8i34\EntityManagerGhostE8260f8 given, called in /.../app/src/Command/CleanDBCommand.php on line 28 

I have checked the documentation and I cannot find how to use EntityManagerInterface in command. Any ideas would be helpful.

Figured out the solution:
I need to pass the command in the constructor
instead of entitymanager to parent constructor like below

parent::__construct('app:cleanDB');
英文:

I am trying to pass EntityManagerInterface to Command and it looks like the parent constructor only accepts string or null

#[AsCommand(
    name: &#39;app:cleanDB&#39;      
)]
class CleanDBCommand extends Command
{

    private $em;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this-&gt;em = $entityManager;

        parent::__construct($entityManager);
    }      

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $date = new \DateTime(&#39;now&#39;);
        $repo = $this-&gt;em-&gt;getRepository(User::class);
        $shortUrl = $repo-&gt;findBy([&#39;createdAt&#39;=&gt;&#39;&lt;&#39;.$date-&gt;format(&#39;Y-m-d&#39;)]);
        $io = new SymfonyStyle($input, $output);             
        $io-&gt;success(&#39;You have a new command! Now make it your own! Pass --help to see your options.&#39;);

        return Command::SUCCESS;
    }
}

I get the following error

> Symfony\Component\Console\Command\Command::__construct(): Argument #1 ($name) must be of type ?string, Container6Yp8i34\EntityManagerGhostE8260f8 given, called in /.../app/src/Command/CleanDBCommand.php on line 28

I have checked the documentation and I cannot find how to use EntityManagerInterface in command. Any ideas would be helpful.

Figured out the solution:
I need to pass the command in the constructor
instead of entitymanager to parent constructor like below

parent::__construct($entityManager);

I need to pass the command as follows

parent::__construct(&#39;app:cleanDB&#39;);

答案1

得分: 1

请注意查看父类 https://github.com/symfony/console/blob/6.3/Command/Command.php#L114。构造函数只接受一个参数,即 $name,它必须严格为字符串或 null。您正尝试传递一个 EntityManagerInterface 对象。无论如何,这都会导致问题。

您是否需要调用父构造函数并传递名称?由于您正在使用属性 #[AsCommand],我认为您在这里定义了您的命令名称,Symfony 应该从属性的反射中获取它。如果您删除父构造函数的参数,应该可以正常工作。在构造函数中,如果不传递任何内容,它将执行静态反射检查:
https://github.com/symfony/console/blob/6.3/Command/Command.php#L71

另外,由于您正在使用属性,您正在使用新的 PHP 8,我建议为您的变量编写类型,并使用更短、更现代的表示法,整个命令应该如下所示。

#[AsCommand(name: 'app:cleanDB')]
class CleanDBCommand extends Command
{    
    public function __construct(
        private EntityManagerInterface $em,
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $date = new \DateTime('now');
        $repo = $this->em->getRepository(User::class);
        $shortUrl = $repo->findBy(['createdAt' => '<'.$date->format('Y-m-d')]);
        $io = new SymfonyStyle($input, $output);             
        $io->success('You have a new command! Now make it your own! Pass --help to see your options.');

        return Command::SUCCESS;
    }
}

如果您不熟悉我如何编写构造函数的方式,这里有一些内容可供阅读:
https://www.php.net/releases/8.0/en.php#constructor-property-promotion

如果您使用 PHP 8.1,您可以在构造函数中编辑以下行:
https://www.php.net/releases/8.1/en.php#readonly_properties

private readonly EntityManagerInterface $em,
英文:

Look at the parent class here https://github.com/symfony/console/blob/6.3/Command/Command.php#L114. The constructor takes only one argument and that is $name which must be strictly string or null. You are trying to pass an EntityManagerInterface object. This will always blow up, no matter what.

Do you need to call the parent constructor with the name anyway? Since you are using the attribute #[AsCommand], I suppose you are defining the name of your command here and the Symfony should get it from the Reflection of the attribute. If you remove your parent constructor argument, it should work just fine. Here you can see that in constructor, if you do not pass anything, it will do the static reflection check:
https://github.com/symfony/console/blob/6.3/Command/Command.php#L71

Also, since you are using attributes, you are on new PHP 8, and I suggest to write types of your variables, also using shorter and modern notation and the whole command should look like this.

#[AsCommand(name: &#39;app:cleanDB&#39;)]
class CleanDBCommand extends Command
{    
    public function __construct(
        private EntityManagerInterface $em,
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $date = new \DateTime(&#39;now&#39;);
        $repo = $this-&gt;em-&gt;getRepository(User::class);
        $shortUrl = $repo-&gt;findBy([&#39;createdAt&#39;=&gt;&#39;&lt;&#39;.$date-&gt;format(&#39;Y-m-d&#39;)]);
        $io = new SymfonyStyle($input, $output);             
        $io-&gt;success(&#39;You have a new command! Now make it your own! Pass --help to see your options.&#39;);

        return Command::SUCCESS;
    }
}

If you are not familiar with the way how I wrote the constructor, here you have something to read:
https://www.php.net/releases/8.0/en.php#constructor-property-promotion

If you are using PHP 8.1, you can edit the line in the constructor
https://www.php.net/releases/8.1/en.php#readonly_properties

private readonly EntityManagerInterface $em,

huangapple
  • 本文由 发表于 2023年7月6日 18:54:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628077.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定