【问题标题】:Symfony Console : Confused about servicesSymfony 控制台:对服务感到困惑
【发布时间】:2019-10-11 11:28:09
【问题描述】:

我使用 Symfony 控制台作为独立的来创建 CLI 应用程序。

Symfony 控制台文档在服务方面一目了然。有人可以给我一个实际的例子来说明它是如何工作的吗?

例如,在您拥有的文档中:

我真的很困惑!

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

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

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

【问题讨论】:

  • 当然,$this->userManager = $userManager; 但我说的是UserManager“服务”提供的->create() 位?我看不出它如何适应 Symfony 控制台生命周期,文档也没有提供任何实际示例。
  • @LittleCode UserManager 是一个应该存在的类,并且应该有一个 create 方法。你可以想象用 UserManager 替换你自己注册为服务的类symfony 的服务容器。
  • 澄清一下,您是在 Symfony 框架中使用控制台命令还是单独使用控制台组件?您的问题表明它是一个独立的命令。在这种情况下,容器(及其服务)不可用。
  • @Cerad 只是独立的 (php composer.phar require symfony/console)
  • 好的。您正在查看如何在框架文档中使用控制台命令。您需要查看独立文档:symfony.com/doc/current/components/console.html 您不会在其中看到任何提及容器和服务的内容,因为甚至没有加载容器组件,更不用说配置了。可以安装容器,但最好的选择可能是只使用框架骨架,直到您感到舒服为止。骨架为您提供容器、控制台和一些配置。

标签: php symfony symfony4


【解决方案1】:

基本上这个想法是,您的 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 的文档。

替代方法

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

$application = new Application();

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

$application->run();

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

tl;博士

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多