简单的解决方案
如果您正在实现 Symfony 命令(可以在 cron 选项卡中执行),您可以从该命令访问服务容器。
<?php
namespace MyProject\MyBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateCommand extends ContainerAwareCommand
{
protected $em;
protected function configure()
{
$this->setName('myproject:mybundle:update') ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
}
}
这样,您可以从命令获取实体管理器,并且不需要将此类声明为服务。因此,您可以删除在services.yml
file.
另一种解决方案(更清洁)
该解决方案可以更好地分离关注点,因此可以轻松进行单元测试并在 Symfony 应用程序的其他部分中重用(不仅仅是作为命令)。
将“更新”命令的所有逻辑部分移至您将声明为服务的专用类:
<?php
namespace MyProject\MyBundle\Service;
use Doctrine\ORM\EntityManager;
class MyUpdater
{
protected $em;
public function __construct($em)
{
$this->em = $em;
}
public function runUpdate()
{
// All your logic code here
}
}
将其声明为您的服务services.yml
file:
services:
myproject.mybundle.myupdater:
class: MyProject\MyBundle\Service\MyUpdater
arguments: ['@doctrine.orm.entity_manager']
只需从您的命令调用您的服务:
<?php
namespace MyProject\MyBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('myproject:mybundle:update') ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$myUpdater = $this->getContainer()->get('myproject.mybundle.myupdater');
$myUpdater->runUpdate();
}
}