TL; DR
我正在创建控制台垃圾收集器,它应该能够从容器中获取服务。 它是基本的,几乎直接来自手册:
<?php
namespace SomeBundle\Console\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand,
Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputInterface,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console\Output\OutputInterface;
class GarbageCollector extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('garbage:collect')
->setDescription('Collect garbage')
->addArgument(
'task',
InputArgument::REQUIRED,
'What task to execute?'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$task = $input->getArgument('task');
//...
$_container = $this->getContainer();
}
}
然后我试图通过application.php
来控制它:
#!/usr/bin/env php
<?php
// application.php
require_once __DIR__.'/../vendor/autoload.php';
use SomeBundle\Console\Command\GarbageCollector;
use Symfony\Bundle\FrameworkBundle\Console\Application;
$application = new Application();
$application->add(new GarbageCollector);
$application->run();
产生致命错误:
参数1传递给 Symfony \ Bundle \ FrameworkBundle \ Console \ Application :: __ construct()必须 实现接口Symfony \ Component \ HttpKernel \ Kernel Interface, 没有给出
手册说我唯一需要做的就是用ContainerAwareCommand
来扩展我的课程,但是缺少了一些东西。我已经写了一些废话代码,将Kernel
传递给Application()
:
#!/usr/bin/env php
<?php
// application.php
require_once __DIR__.'/../vendor/autoload.php';
require_once __DIR__.'/AppKernel.php';
use SomeBundle\Console\Command\GarbageCollector;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->add(new GarbageCollector);
$application->run();
它有效,但感觉很恶心。
我需要如何ContainerAwareCommand
实施控制台应用?提前谢谢。
答案 0 :(得分:4)
Symfony2通过其控制台运行程序提供调用自定义命令的功能,它将处理服务容器的注入。您需要做的就是在已注册的包中创建命令,它将自动为您提供。您正在框架之外初始化命令,这就是除非您手动注入容器,否则容器无法使用的原因。
您可以在这里参考食谱:
http://symfony.com/doc/current/cookbook/console/console_command.html
您可以通过运行获得所有可用命令的列表:
php app/console
另外,为什么要在/中为PHP创建垃圾收集器?只是好奇,因为根据我的理解,在脚本执行结束后,内存将被释放。
答案 1 :(得分:1)
从4.1版开始,您可以在构造函数中注入容器服务。
namespace App\Commands;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MyCommand extends Command {
protected $container;
public function __construct(ContainerInterface $container) {
$this->container = $container;
parent::__construct();
}
protected function configure() {
// ...
}
protected function execute(InputInterface $input, OutputInterface $output) {
// You must make Some\Service\Class public.
// Documentation at https://symfony.com/doc/current/service_container.html#public-versus-private-services
$some_service = $this->container->get('Some\Service\Class');
}
}