简体   繁体   English

Symfony控制台应用程序:依赖注入

[英]Symfony console application: dependency injection

A Symfony novice here. 这是一个Symfony新手。 After reading some of the Symfony documentation and some answers here at SO, I am now almost completely confused. 在SO阅读了一些Symfony文档和一些答案后,我现在几乎完全糊涂了。 I am trying to use the console application component and create a small db-aware console application. 我正在尝试使用控制台应用程序组件并创建一个小型的db-aware控制台应用程序。

Many people state that in order to use Symfony's DI features it would be enough to inherit my command class not from Symfony\\Component\\Console\\Command\\Command but from ContainerAwareCommand. 许多人声称,为了使用Symfony的DI功能,继承我的命令类就足够了,而不是从Symfony \\ Component \\ Console \\ Command \\ Command继承,而是从ContainerAwareCommand继承。 However when I try this I get a Method Not Found error on an application::getKernel() call. 但是,当我尝试这个时,我在application :: getKernel()调用上得到一个Method Not Found错误。

I have a feeling that DI features are in fact not available in a console application based on the console component . 我感觉DI功能实际上在基于控制台组件的控制台应用程序中不可用。 Is there another kind of Symfony console application, for example, based on the full-blown framework? 是否有另一种Symfony控制台应用程序,例如,基于完整的框架?

I very much like the simple framework provided by the console component Symfony\\Component\\Console\\Application. 我非常喜欢控制台组件Symfony \\ Component \\ Console \\ Application提供的简单框架。 But the question is then - what to do for dependency injection and DBAL? 但问题是 - 如何处理依赖注入和DBAL? All examples that I find seem to refer to the full Symfony framework and get me just all the more stuck. 我找到的所有示例似乎都引用了完整的Symfony框架,让我更加困难。

Just a quick update on my progress if anybody stumbles upon the same problems. 如果有人遇到同样的问题,只需快速更新我的进度。

  1. I incorporated into my project the PHP-DI dependency injection framework, which seems to be working fairly well with no configuration (so far) - it figures out quite a lot by reflection, actually. 我在我的项目中加入了PHP-DI依赖注入框架,它似乎在没有配置的情况下运行得相当好(到目前为止) - 它实际上通过反射得出了很多。
  2. The same way, Doctrine\\DBAL is included as a standalone library (I opted against the O/RM part of it, as it is really a tiny project and I'm on a much firmer ground with SQL than anything else) and the connection is simply returned by a connection provider which is injected wherever needed by the DI. 同样,Doctrine \\ DBAL作为一个独立的库包含在内(我选择了它的O / RM部分,因为它实际上是一个很小的项目,而且我在SQL上比其他任何东西都更加坚固)和连接简单地由连接提供程序返回,该连接提供程序在DI需要的地方注入。

One thing I couldn't figure out is how to have the command classes instantiated by the DI library without my help, so I actually had to inject the container itself into my overridden application class and override the getDefaultCommands() where I then pull the instances out of the container manually. 我无法弄清楚的一件事是如何在没有我的帮助的情况下让DI库实例化命令类,所以我实际上必须将容器本身注入我重写的应用程序类并覆盖getDefaultCommands()然后我拉出实例手动从容器中取出。 Not ideal but will have to do for now. 不理想,但现在必须做。

If your command extends ContainerAwareCommand 如果您的命令扩展了ContainerAwareCommand

...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
...

class MyCommand extends ContainerAwareCommand
{

The DI container is available with the getContainer() method. DI容器可以使用getContainer()方法。 (like in a standard controller), ex: (比如在标准控制器中),例如:

$this->validator = $this->getContainer()->get('validator');

I don't know if your question is still relevant, but I have an answer as I stumbled across the same problem here. 我不知道你的问题是否仍然相关,但我有一个答案,因为我偶然发现了同样的问题。

You just have to create the kernel yourself and give it to the \\Symfony\\Bundle\\FrameworkBundle\\Console\\Application that extends the basic \\Symfony\\Component\\Console\\Application. 您只需自己创建内核并将其提供给扩展基本\\ Symfony \\ Component \\ Console \\ Application的\\ Symfony \\ Bundle \\ FrameworkBundle \\ Console \\ Application。

<?php
// CronRun.php

require __DIR__.'/../../../../vendor/autoload.php';
require_once __DIR__.'/../../../../app/AppKernel.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();

$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
$application->add(new \KingdomHall\TaskBundle\Command\CronCommand());
$input = new \Symfony\Component\Console\Input\StringInput('k:c:r');
$application->run($input);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM