Symfony 4.2+:替代 ContainerAwareCommand 的 getContainer->get()
Symfony 4.2+: Replacement for ContainerAwareCommand's getContainer->get()
我的目标
在 Plesk 中,我想 运行 一个经常使用 PHP 7.2 的 PHP 脚本。它必须是 PHP 脚本而不是控制台命令(请参阅 "my environment" 了解更多详细信息)。我当前基于 Symfony 4.2 的实现工作正常,但它被标记为 已弃用 。
如前所述here, the ContainerAwareCommand
is marked deprecated
in Symfony 4.2. Unfortunately, the referenced article关于将来如何解决此问题的信息不包含有关它的信息。
我的环境
我的共享虚拟主机 (Plesk) 运行s 与 PHP 7.0 但允许脚本 运行 与 PHP 7.2。如果它直接 运行s PHP 脚本并且 而不是 作为控制台命令,则以后才有可能。我需要 PHP 7.2.
我知道 Symfony 中的 injection types。根据我目前的知识,这个问题只能通过使用 getContainer
方法或手动提供所有服务来解决,例如通过构造函数,这将导致代码混乱。
当前解决方案
文件:cron1.php
<?php
// namespaces, Dotenv and gathering $env and $debug
// ...
$kernel = new Kernel($env, $debug);
$app = new Application($kernel);
$app->add(new FillCronjobQueueCommand());
$app->setDefaultCommand('fill_cronjob_queue');
$app->run();
文件:FillCronjobQueueCommand.php
<?php
// ...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class FillCronjobQueueCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('fill_cronjob_queue');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// using "$this->getContainer()" is deprecated since Symfony 4.2
$manager = $this->getContainer()->get('doctrine')->getManager();
$cron_queue_repo = $manager->getRepository(CronjobQueue::class);
$cronjobs = $manager->getRepository(Cronjob::class)->findAll();
$logger = $this->getContainer()->get('logger');
// ...
}
}
现在回答
就我而言,复制 ContainerAwareCommand class 似乎是最好的方法,只要没有另外说明(感谢 "Cerad")。这使我能够保留当前功能并摆脱不推荐使用的警告。对我来说,它也是临时解决方案(直到 Hoster 升级到 PHP 7.2),因此对 Symfony 未来的主要升级没有影响。
不过,我推荐下面的答案,并会在未来实施。
推荐答案
根据这篇博文 post 在 symfony 网站上 Deprecated ContainerAwareCommand
The alternative is to extend commands from the Command class and use proper service injection in the command constructor
所以正确的方法是:
<?php
// ...
use Symfony\Component\Console\Command\Command
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use PSR\Log\LoggerInterface;
class FillCronjobQueueCommand extends Command
{
public function __construct(EntityManagerInterface $manager, LoggerInterface $logger)
{
$this->manager = $manager;
$this->logger = $logger;
}
protected function configure()
{
$this->setName('fill_cronjob_queue');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$cron_queue_repo = $this->manager->getRepository(CronjobQueue::class);
$cronjobs = $this->manager->getRepository(Cronjob::class)->findAll();
// ...
}
}
我的目标
在 Plesk 中,我想 运行 一个经常使用 PHP 7.2 的 PHP 脚本。它必须是 PHP 脚本而不是控制台命令(请参阅 "my environment" 了解更多详细信息)。我当前基于 Symfony 4.2 的实现工作正常,但它被标记为 已弃用 。
如前所述here, the ContainerAwareCommand
is marked deprecated
in Symfony 4.2. Unfortunately, the referenced article关于将来如何解决此问题的信息不包含有关它的信息。
我的环境
我的共享虚拟主机 (Plesk) 运行s 与 PHP 7.0 但允许脚本 运行 与 PHP 7.2。如果它直接 运行s PHP 脚本并且 而不是 作为控制台命令,则以后才有可能。我需要 PHP 7.2.
我知道 Symfony 中的 injection types。根据我目前的知识,这个问题只能通过使用 getContainer
方法或手动提供所有服务来解决,例如通过构造函数,这将导致代码混乱。
当前解决方案
文件:cron1.php
<?php
// namespaces, Dotenv and gathering $env and $debug
// ...
$kernel = new Kernel($env, $debug);
$app = new Application($kernel);
$app->add(new FillCronjobQueueCommand());
$app->setDefaultCommand('fill_cronjob_queue');
$app->run();
文件:FillCronjobQueueCommand.php
<?php
// ...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class FillCronjobQueueCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('fill_cronjob_queue');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// using "$this->getContainer()" is deprecated since Symfony 4.2
$manager = $this->getContainer()->get('doctrine')->getManager();
$cron_queue_repo = $manager->getRepository(CronjobQueue::class);
$cronjobs = $manager->getRepository(Cronjob::class)->findAll();
$logger = $this->getContainer()->get('logger');
// ...
}
}
现在回答
就我而言,复制 ContainerAwareCommand class 似乎是最好的方法,只要没有另外说明(感谢 "Cerad")。这使我能够保留当前功能并摆脱不推荐使用的警告。对我来说,它也是临时解决方案(直到 Hoster 升级到 PHP 7.2),因此对 Symfony 未来的主要升级没有影响。
不过,我推荐下面的答案,并会在未来实施。
推荐答案
根据这篇博文 post 在 symfony 网站上 Deprecated ContainerAwareCommand
The alternative is to extend commands from the Command class and use proper service injection in the command constructor
所以正确的方法是:
<?php
// ...
use Symfony\Component\Console\Command\Command
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use PSR\Log\LoggerInterface;
class FillCronjobQueueCommand extends Command
{
public function __construct(EntityManagerInterface $manager, LoggerInterface $logger)
{
$this->manager = $manager;
$this->logger = $logger;
}
protected function configure()
{
$this->setName('fill_cronjob_queue');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$cron_queue_repo = $this->manager->getRepository(CronjobQueue::class);
$cronjobs = $this->manager->getRepository(Cronjob::class)->findAll();
// ...
}
}