Symfony控制台:对服务感到困惑

时间:2019-10-11 11:28:09

标签: php symfony symfony4

我正在独立使用Symfony Console创建CLI应用程序。

关于服务,Symfony控制台文档非常清晰。有人可以给我一个实际的例子吗?

例如,您在文档中拥有:

我真的很困惑!

例如,“从服务容器中获取服务”中的示例显示了一个示例$this->userManager->create($input->getArgument('username'));

但是它没有显示给我。如何创建具有userManager函数的神奇create类?

如果我将userManager创建为标准命令,那么鉴于Symfony控制台只有三个生命周期,我看不到如何创建子功能? initialize()interact()execute()

1 个答案:

答案 0 :(得分:4)

基本上,您的Command描述了它将在其构造函数中使用的服务,因此,如果您只想要UserManager,它将看起来像这样:


class MyCommand extends Command
{
    private $userManager;

    public function __construct(UserManager $userManager)
    {
        // Make sure to call the parent constructor
        parent::__construct(null);

        $this->userManager = $userManager;
    }

    // ...
}

Symfony控制台没有说明服务的创建,因为这不是它的责任,这就是Service Container(是依赖注入组件的一部分)在典型的Symfony应用程序中的作用,并且您也可以使用它,但是可能在您的小型CLI工具中会显得有些过分。

简单的方法

在您bin/console.php(或其等效项)中,您可以在添加如下命令时实例化所有服务:

use Symfony\Component\Console\Application;

$application = new Application();

$userManager = new UserManager(...);
$application->add(new MyCommand($userManager));

$application->run();

方法少

您可以想象这会变得很繁琐和烦人,特别是如果您需要不同的配置。您可以独立使用服务容器,并使其读取服务配置(基本上是$app = new Application()$app->run()之间的全部内容的表示形式:

$containerBuilder = new ContainerBuilder();

$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__));
$loader->load('config.yaml');

// ...
$containerBuilder->compile();

请参阅Compiling container的文档。

替代方法

如果您希望保留用于创建所有这些服务的代码,并且不希望使用容器,则可以创建Factory类,然后创建UserManager(在需要时,而不是在先创建所有服务):

$application = new Application();

$userManagerFactory = new UserManagerFactory() ;
$application->add($userManagerFactory->createUserManager());

$application->run();

如果您认为配置和编译太多工作,也可以使用其他容器代替Symfony的Container。例如,有一个非常轻量的基于数组的解决方案称为Pimple,它可能更适合您的用例,或者您可以使用其中的许多其他库之一。

tl; dr

创建服务不是控制台组件的责任,因此没有说明。有许多不同的方法具有不同的优点/缺点,例如仅在需要时实例化服务与获取容器(或容纳服务的类似容器的东西)所需的配置。

相关问题