gpt4 book ai didi

php - 在没有 Symfony 框架包的情况下,如何使用依赖注入(inject)的 Symfony 控制台?

转载 作者:搜寻专家 更新时间:2023-10-31 21:22:21 25 4
gpt4 key购买 nike

我有一个命令行应用程序,到目前为止它使用 Symfony 依赖注入(inject)组件。我现在发现我想添加命令行选项并改进输出格式,而 Symfony 控制台组件似乎是一个不错的选择。

但是,我无法理解如何让我的 Symfony 控制台命令类接收容器对象。

我找到的文档使用了 ContainerAwareCommand 类,但它来自 FrameworkBundle——添加到纯 CLI 应用程序似乎需要大量开销,因为它需要进一步的捆绑,例如路由、http、配置、缓存等等,这些都与我无关。

(现有的 SO 问题 How can i inject dependencies to Symfony Console commands? 也假定了 FrameworkBundle,顺便说一句。)

我在这里创建了一个测试存储库,其中包含一个说明问题的基本命令:https://github.com/joachim-n/console-with-di

最佳答案

Symfony 3/4/5 方式

自 2018 年以来 Symfony 3.4+ DI features ,您可以使用命令作为服务

您可以 find working demo here ,感谢@TravisCarden

简而言之:

1。应用内核

<?php

# app/Kernel.php

namespace App;

use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class AppKernel extends Kernel
{
public function registerBundles(): array
{
return [];
}

public function registerContainerConfiguration(LoaderInterface $loader): void
{
$loader->load(__DIR__.'/../config/services.yml');
}

protected function build(ContainerBuilder $containerBuilder): void
{
$containerBuilder->addCompilerPass($this->createCollectingCompilerPass());
}

private function createCollectingCompilerPass(): CompilerPassInterface
{
return new class implements CompilerPassInterface
{
public function process(ContainerBuilder $containerBuilder)
{
$applicationDefinition = $containerBuilder->findDefinition(Application::class);

foreach ($containerBuilder->getDefinitions() as $definition) {
if (! is_a($definition->getClass(), Command::class, true)) {
continue;
}

$applicationDefinition->addMethodCall('add', [new Reference($definition->getClass())]);
}
}
};
}
}

2。服务

# config/services.yml

services:
_defaults:
autowire: true

App\:
resource: '../app'

Symfony\Component\Console\Application:
public: true

3。 bin文件

# index.php

require_once __DIR__ . '/vendor/autoload.php';

use Symfony\Component\Console\Application;

$kernel = new AppKernel;
$kernel->boot();

$container = $kernel->getContainer();
$application = $container->get(Application::class)
$application->run();

运行它

php index.php

如果您对更详细的解释感兴趣,我写了一篇文章 Why You Should Combine Symfony Console and Dependency Injection .

关于php - 在没有 Symfony 框架包的情况下,如何使用依赖注入(inject)的 Symfony 控制台?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44057062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com