没有完整堆栈框架的 Symfony 组件
Symfony Components without the full stack framework
我在创建您自己的 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();
}
}
Returns
Fatal error: Uncaught ArgumentCountError: Too few arguments to function Demo\DemoController::__construct(), 0 passed
我怎样才能让它工作?或者,如何将容器注入控制器构造函数?
你实际上非常接近,做得很好。我认为您将 ContainerAwareInterface 与 ContainerControllerResolver 建议混合使用。真的是两个不同的概念。看起来您也尝试制作自己的 ControllerResolver class 但您没有更新 container.php 来使用它。无论如何,此时不需要自定义解析器。
我还不小心误导了您,建议您使用名为 'container' 的服务。它实际上被称为'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' 或不使用。但大多数时候,您的应用程序级别的东西应该只使用 class 名称作为服务 ID。特别是您需要使用控制器 class 名称以允许 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)]);
应该就可以了。享受吧。
我在创建您自己的 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();
}
}
Returns
Fatal error: Uncaught ArgumentCountError: Too few arguments to function Demo\DemoController::__construct(), 0 passed
我怎样才能让它工作?或者,如何将容器注入控制器构造函数?
你实际上非常接近,做得很好。我认为您将 ContainerAwareInterface 与 ContainerControllerResolver 建议混合使用。真的是两个不同的概念。看起来您也尝试制作自己的 ControllerResolver class 但您没有更新 container.php 来使用它。无论如何,此时不需要自定义解析器。
我还不小心误导了您,建议您使用名为 'container' 的服务。它实际上被称为'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' 或不使用。但大多数时候,您的应用程序级别的东西应该只使用 class 名称作为服务 ID。特别是您需要使用控制器 class 名称以允许 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)]);
应该就可以了。享受吧。