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

4
一个Symfony新手在这里。在阅读了一些Symfony文档和Stack Overflow上的一些答案之后,我现在几乎完全困惑了。 我正在尝试使用控制台应用程序组件并创建一个小型的数据库感知控制台应用程序。
许多人表示,为了使用Symfony的DI功能,只需将我的命令类从Symfony\Component\Console\Command\Command继承到ContainerAwareCommand即可。 但是,当我尝试这样做时,在application::getKernel()调用上出现了“方法未找到”错误。
我有一种感觉,基于控制台组件的控制台应用程序实际上不能使用DI功能。是否有另一种Symfony控制台应用程序,例如基于完整的框架?
我非常喜欢由Symfony\Component\Console\Application提供的简单框架。但问题是,如何进行依赖注入和DBAL?我找到的所有示例似乎都是针对完整的Symfony框架,并使我越来越困惑。

考虑到您是S2的新手,我建议您选择完整的框架来开始。让您的应用程序运行并获得一些使用组件的经验。然后您可以尝试剥离一些东西。特别是如果您想要访问Doctrine 2 DBAL。它的配置有点麻烦。 - Cerad
4个回答

3

如果有人遇到相同的问题,这里是我的进展情况简单更新。

  1. 我在项目中引入了PHP-DI依赖注入框架,目前看来工作得非常好,没有任何配置(目前为止),实际上它通过反射发现了非常多的东西。
  2. 同样地,Doctrine\DBAL被包括在一个独立的库中(我选择不使用它的O/RM部分,因为这真的是一个小项目,而且我对SQL比其他语言都要熟悉得多),连接只是由一个连接提供程序返回,并由DI注入到需要的地方。

有一件事我无法解决,就是如何让DI库自动实例化命令类,所以我不得不将容器本身注入到我的重载应用程序类中,并覆盖getDefaultCommands(),然后手动从容器中获取实例。虽然不理想,但现在只能这样做。


4
嗨,我是PHP-DI的作者。这里有一个在Symfony Console组件中使用它的例子(在Symfony框架之外):https://github.com/mnapoli/IsItMaintained/blob/master/bin/console 如果您有任何问题,请在StackOverflow上使用“php-di”标签进行提问,或进入聊天室:https://gitter.im/mnapoli/PHP-DI - Matthieu Napoli
谢谢提供链接。最终我做了类似的事情,只不过在集成 DI 之前,我在应用程序类中创建了一些默认命令。所以,为了沿着这条路继续前进,我必须将容器注入到应用程序类中,并在那里获取命令实例。目前来看还可以。 - Yuri Makassiouk

1
如果您的命令扩展了ContainerAwareCommand
...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
...

class MyCommand extends ContainerAwareCommand
{

DI容器可通过getContainer()方法获得(如标准控制器中一样),例如:
$this->validator = $this->getContainer()->get('validator');

谢谢您的回答。为了使上面的片段有效,应用程序对象是如何构建的?当我尝试您所建议的内容时,我遇到了一个错误,这个错误我在我的问题中提到了(找不到Application :: getKernel()方法)。这很有道理,因为我构建的应用程序是Symfony \ Component \ Console \ Application的实例,它没有内核。 - Yuri Makassiouk
1
你没有使用全栈框架吗?那很正常,你需要自己构建容器并将其注入到命令中。 - COil
1
不,我不是!这个应用程序不足以使用重型武器。这就是问题所在。由于某种原因,文档对此非常模糊。所以,Symfony\Component\Console\Application等于没有容器,除非我们自己创建。 - Yuri Makassiouk
1
请查看此博客文章:http://dcousineau.com/blog/2013/03/28/using-symfony-console-from-scratch/ - COil

0

你可以使用我刚刚上传到packagist.org的解决方案。它包含完整的工作symfony/dependency-injection。欢迎您尝试一下。使用composer创建您自己的项目composer create-project coral-media/crune project_dir或只需克隆存储库。 https://packagist.org/packages/coral-media/crune 您只需要安装DBAL依赖项(如果您不真正需要ORM,我建议不要使用ORM)。在.env中配置连接参数,然后只需定义一个处理连接的服务即可。可以使用公共的setMyService($myService)方法和@required注释将该服务注入到您的命令中。此外,您还可以创建一个Connection类,并将其绑定为command构造函数中的参数。 crune样板还支持自动线和自动配置功能。


0

我不知道你的问题是否仍然相关,但是我有一个答案,因为我在这里遇到了同样的问题。

你只需要自己创建内核并将其提供给扩展基本 \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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接