【问题标题】:create command line in Symfony 2 : add private fields在 Symfony 2 中创建命令行:添加私有字段
【发布时间】:2025-12-02 05:15:01
【问题描述】:

我阅读了有关在 Symfony 2 中创建命令行的文档。 我想创建一个有点不同的 Command 类。确实,我想将翻译器添加为我班级的私有字段......就像这样:

<?php

namespace myVendor\myBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ThemeCommand extends ContainerAwareCommand {
private $translator;

public function __construct() {
    $this->translator = $this->getContainer()->get('translator');
}

protected function configure() {
    $this->setName('viewkit:color')
         ->setDescription($this->translator->trans('command.theme.description'))
         ->addArgument('theme', InputArgument::REQUIRED, 'le thème jquery');
}

protected function execute(InputInterface $input, OutputInterface $output) {
    $theme = $input->getArgument('theme');        
    $output->writeln($this->translator->trans('command.theme.success'));
}

}

?>

你可以想象它因为构造函数而不起作用,我有这个例外:

Call to a member function getKernel() on a non-object in C:\wamp\www\viewkit\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand.php

问题是抽象类 ContainerAwareCommand 中的 getContainer 方法可能返回 null 并且由于这个类来自 Command.php 类,问题更具体地说是返回非对象(可能为 null)的 Command.php getApplication 方法..

Command.php 类的 application 字段以某种方式被填充,但是由于我的 ThemeCommand 中有我的构造函数,所以出现了问题

所以我的问题是: 如何在我的 ThemeCommand 类中拥有私有字段并使用完善的构造函数对其进行初始化

谢谢


我做了另一个测试,摆脱了构造函数并像文档中那样做......同样的问题,构造函数不是问题,但 getContainer 没有返回对象,因为 Command.php 中的 getApplication为空

【问题讨论】:

  • 你如何从 CLI 调用你的命令?
  • 我用的是netbeans,所以加载了命令行,此时出现异常...如果我不使用翻译器,它可以正常工作

标签: symfony command-line


【解决方案1】:

你忘记调用父构造函数了!

public function __construct() {
    parent::__construct();
    $this->translator = $this->getContainer()->get('translator');
}

【讨论】:

  • 对不起,父类是抽象类,所以没有构造函数
  • 所以我想调用祖父构造函数: Command::__construct()... 但是我每次调用 trans() 方法时都有另一个异常,就像 $translator 不是对象(可能为空)
  • __construct 始终是可调用的(但在静态上下文中),无论是否定义。而且,在这种情况下,ContainerAwareCommand 不会重新定义它,但 Command 会......
  • 尤其是因为抽象类不能被实例化
【解决方案2】:

问题是,当调用configure方法,或者调用constructor时,application对象为null。只有在执行方法中才能调用服务,因为与此同时,应用程序对象已被填充

【讨论】:

  • 我遇到了同样的问题。你能详细说明一下这个答案吗?
  • 已经有一段时间了,但我的意思是我不能在构造函数中调用服务......我必须在方法中调用它。所以我摆脱了我的私人领域,当我需要翻译时(例如在执行方法中)我调用服务 $this->getContainer()->get('translator')->trans()