Symfony 4自定义容器感知命令错误

时间:2018-03-05 13:56:42

标签: php symfony symfony4

我正在尝试在Symfony 4项目中创建自定义命令

class AppOauthClientCreateCommand extends ContainerAwareCommand
{

   protected function configure()
   {
     $this
        ->setName('app:oauth-client:create')
        ->setDescription('Create a new OAuth client');
   }

   protected function execute(InputInterface $input, OutputInterface $output)
   {
    $clientManager = $this->getContainer()->get('fos_oauth_server.client_manager.default');
    $client = $clientManager->createClient();
    $client->setAllowedGrantTypes(array(OAuth2::GRANT_TYPE_USER_CREDENTIALS));
    $clientManager->updateClient($client);

    $output->writeln(sprintf('client_id=%s_%s', $client->getId(), $client->getRandomId()));
    $output->writeln(sprintf('client_secret=%s', $client->getSecret()));
   }
}

尝试运行此命令时出现以下错误

  

编译容器时,“fos_oauth_server.client_manager.default”服务或别名已被删除或内联。你应该是      使其公开,或直接停止使用容器并改为使用依赖注入。

如何将供应商服务公开,或者我在命令配置中遗漏了什么?

2 个答案:

答案 0 :(得分:3)

问题是,自Symfony 4以来,所有服务都是私有的。实际上,使用服务容器的get方法无法获得私有服务。

您应该避免在服务中注入整个contanier(或通过扩展ContainerAwareCommand来命令)。相反,您应该只注入所需的服务:

class AppOauthClientCreateCommand
{
   /**
    * @var ClientManagerInterface
    */
   private $clientManager;

   public function __construct(ClientManagerInterface $clientManager)
   {
       $this->clientManager = $clientManager;
   }

   protected function configure()
   {
       ...
   }

   protected function execute(InputInterface $input, OutputInterface $output)
   {
        $client = $this->clientManager->createClient();
        ...
   }
}

如果ClientManagerInterface未自动装配,则必须在您的services.yaml中配置具有适当依赖关系的AppOauthClientCreateCommand。类似的东西:

services:
    App\Command\AppOauthClientCreateCommand:
        arguments:
            $clientManager: "@fos_oauth_server.client_manager.default"

希望这有帮助。

答案 1 :(得分:1)

您需要检查./bin/console debug:autowiring命令的输出以获取相应的接口,以便在构造函数中使用'fos_oauth_server.client_manager。*'。应该已经设置了自动装配,以允许容器识别并从那里插入它。

这将需要FosOauthServer支持SF4 - 并且在构造函数中记得还要调用parent::__construct();来正确设置命令。你可以这样做,仍然使用ContainerAwareCommand来容器中的->get()其他东西 - 但是你可能会随着时间的推移而远离它。