【问题标题】:Symfony Components without the full stack framework没有完整堆栈框架的 Symfony 组件
【发布时间】:2021-05-23 20:23:05
【问题描述】:

我在创建您自己的 PHP 框架 (https://symfony.com/doc/current/create_framework/index.html) 之后的项目中使用 Symfony DI、Http、内核、路由。使用 is_leap_year 应用演示目的没问题。

我试图弄清楚如何将服务和容器注入到路由中定义的自定义控制器中,该控制器仅使用 Symfony 组件,而不是框架包。

container.php

// add demo service into the service container
$containerBuilder->register('demo.service', '\Demo\DemoService');

// add dependent service into the controller container
$containerBuilder->register('dependent.controller', '\Demo\DemoController')
    ->setArguments([new Reference('demo.service')]);

// fetch service from the service container
// Echoing Works fine! But no service in controller
//echo $containerBuilder->get('dependent.controller')->helloWorld();

App.php

// nok with dependency
$routes->add('hello', new Routing\Route('/hello', [
    '_controller' => 'Demo\DemoController::helloWorld',
]));

// ok with no dependency
$routes->add('hello2', new Routing\Route('/hello2', [
    '_controller' => 'Demo\DemoService::helloWorld',
]));

还有DemoController.php

<?php declare(strict_types=1);

namespace Demo;

class DemoController
{
  private $demo_service;

  public function __construct(\Demo\DemoService $demoService)
  {
    $this->demo_service = $demoService;
  }

  public function helloWorld()
  {
    return $this->demo_service->helloWorld();
  }
}

返回

Fatal error: Uncaught ArgumentCountError: Too few arguments to function Demo\DemoController::__construct(), 0 passed

我怎样才能让它工作?或者,如何将容器注入控制器构造函数?

这里的例子https://github.com/Monnomcjo/symfony-simplex

【问题讨论】:

  • 你好。请添加您的services.yaml 文件的内容
  • 您好,没有 services.yaml。我不使用 symfony 框架包,而是我自己的基于symfony.com/doc/current/create_framework/index.html。一切正常,但将服务注入自定义控制器。
  • 为了进行任何类型的依赖注入,您需要某种依赖注入容器。 The last link 在构建您自己的框架页面上将至少为您提供构造函数注入的基础知识。了解正在发生的事情将是另一次冒险。在某些时候,只使用 Symfony 框架框架可能更容易,但绝对值得学习如何使用容器。
  • 我查看了您链接的单一存储库。目前,ControllerResolver 通过新建控制器类名来实例化控制器。您想将 ControllerResolver 替换为 ContainerControllerResolver ,它将首先查看是否定义了控制器服务并使用它。这会让你注入构造函数。
  • Arf..ContainerControllerResolver 需要 ContainerInterface...

标签: php symfony no-framework


【解决方案1】:

实际上,你在那里做得非常好。我认为您将 ContainerAwareInterface 与 ContainerControllerResolver 建议混合在一起。真的是两个不同的概念。看起来您也尝试制作自己的 ControllerResolver 类,但您没有更新 container.php 来使用它。无论如何,此时不需要自定义解析器。

我还无意中误导了您,建议有一项名为“容器”的服务。它实际上被称为“service_container”。

# container.php
$containerBuilder->register('container_controller_resolver', HttpKernel\Controller\ContainerControllerResolver::class)
    ->setArguments([new Reference('service_container')]); 

$containerBuilder->register('framework', Framework::class)
    ->setArguments([
        new Reference('dispatcher'),
        new Reference('container_controller_resolver'), // Changed
        new Reference('request_stack'),
        new Reference('argument_resolver'),
        //new Reference('demo.service'), // No need for these
        //new Reference('dependent.controller'),
    ])
;

此外,按照惯例,一些框架服务使用 id 之类的 'framework' 或其他。但大多数时候,您的应用程序级别的东西应该只使用类名作为服务 ID。特别是您需要使用控制器类名称来允许 ContainerControllerResolver 找到它。当您冒险使用容器的自动连接功能时,它也会很有用。

// add demo service into the service container
$containerBuilder->register(\Demo\DemoService::class, \Demo\DemoService::class);

// add dependent service into the controller container
$containerBuilder->register(\Demo\DemoController::class,\Demo\DemoController::class)
    ->setArguments([new Reference(\Demo\DemoService::class)]);

应该这样做。享受吧。

【讨论】:

  • 精彩@cerad。你让我开心。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 2016-12-20
  • 2012-04-26
  • 1970-01-01
相关资源
最近更新 更多