英文:
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: '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($entityManager);
I need to pass the command as follows
parent::__construct('app:cleanDB');
答案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: '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;
}
}
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,
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论