symfony 5.1:如何将控制器定义为服务
symfony 5.1: how to define a controller as a service
说到 Symfony,我有点菜鸟。我正在尝试使用接受服务作为构造函数参数的控制器创建一个包;但是,我收到此错误:
The controller for URI "/heartbeat" is not callable: Controller
"Acme\HeartbeatBundle\Controller\HeartbeatController" has
required constructor arguments and does not exist in the container.
Did you forget to define the controller as a service?
这是Resources/config/services.xml
:
<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="acme_heartbeat.service.heartbeat_service"
class="Acme\HeartbeatBundle\Service\HeartbeatService">
<argument type="string" id="heartbeat.address"/>
</service>
<service id="acme_heartbeat.controller.heartbeat_controller"
class="Acme\HeartbeatBundle\Controller\HeartbeatController">
<argument type="service" id="acme_heartbeat.service.heartbeat_service"/>
<tag name="controller.service_arguments" />
</service>
...
</services>
</container>
这是Resources/config/routes.xml
:
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing
https://symfony.com/schema/routing/routing-1.0.xsd">
<route id="heartbeat" path="/heartbeat" controller="Acme\HeartbeatBundle\Controller\HeartbeatController::heartbeat" methods="GET" />
</routes>
主要的 Symfony 应用 config/routes.yaml
:
heartbeat:
resource: '@AcmeHeartbeatBundle/Resources/config/routes.xml'
Controller/HeartbeatController.php
:
<?php
declare(strict_types=1);
namespace Acme\HeartbeatBundle\Controller;
use Acme\HeartbeatBundle\Service\HeartbeatService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class HeartbeatController extends AbstractController
{
public function __construct(HeartbeatService $hbs)
{
...
}
...
}
这是Service/HeartbeatService.php
:
<?php
namespace Acme\HeartbeatBundle\Service;
class HeartbeatService
{
...
}
有人能告诉我我做错了什么吗?
从 Symfony 4 开始,首选的服务命名方式是 use the FQCN as the service id in order to ease autowiring。您使用了 old-style 字符串 ID,因此即使 class 匹配,当 Symfony 按预期 ID 查找它时,它也找不到它。
这很容易解决,要么将定义更改为
<service id="Acme\HeartbeatBundle\Controller\HeartbeatController">
或添加别名:
<service id="Acme\HeartbeatBundle\Controller\HeartbeatController"
alias="acme_heartbeat.controller.heartbeat_controller" />
您也可以将路由定义更改为已注册的服务 ID (acme_heartbeat.controller.heartbeat_controller::index
),但我会遵循建议并选择第一个选项。
说到 Symfony,我有点菜鸟。我正在尝试使用接受服务作为构造函数参数的控制器创建一个包;但是,我收到此错误:
The controller for URI "/heartbeat" is not callable: Controller
"Acme\HeartbeatBundle\Controller\HeartbeatController" has
required constructor arguments and does not exist in the container.
Did you forget to define the controller as a service?
这是Resources/config/services.xml
:
<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="acme_heartbeat.service.heartbeat_service"
class="Acme\HeartbeatBundle\Service\HeartbeatService">
<argument type="string" id="heartbeat.address"/>
</service>
<service id="acme_heartbeat.controller.heartbeat_controller"
class="Acme\HeartbeatBundle\Controller\HeartbeatController">
<argument type="service" id="acme_heartbeat.service.heartbeat_service"/>
<tag name="controller.service_arguments" />
</service>
...
</services>
</container>
这是Resources/config/routes.xml
:
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing
https://symfony.com/schema/routing/routing-1.0.xsd">
<route id="heartbeat" path="/heartbeat" controller="Acme\HeartbeatBundle\Controller\HeartbeatController::heartbeat" methods="GET" />
</routes>
主要的 Symfony 应用 config/routes.yaml
:
heartbeat:
resource: '@AcmeHeartbeatBundle/Resources/config/routes.xml'
Controller/HeartbeatController.php
:
<?php
declare(strict_types=1);
namespace Acme\HeartbeatBundle\Controller;
use Acme\HeartbeatBundle\Service\HeartbeatService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class HeartbeatController extends AbstractController
{
public function __construct(HeartbeatService $hbs)
{
...
}
...
}
这是Service/HeartbeatService.php
:
<?php
namespace Acme\HeartbeatBundle\Service;
class HeartbeatService
{
...
}
有人能告诉我我做错了什么吗?
从 Symfony 4 开始,首选的服务命名方式是 use the FQCN as the service id in order to ease autowiring。您使用了 old-style 字符串 ID,因此即使 class 匹配,当 Symfony 按预期 ID 查找它时,它也找不到它。
这很容易解决,要么将定义更改为
<service id="Acme\HeartbeatBundle\Controller\HeartbeatController">
或添加别名:
<service id="Acme\HeartbeatBundle\Controller\HeartbeatController"
alias="acme_heartbeat.controller.heartbeat_controller" />
您也可以将路由定义更改为已注册的服务 ID (acme_heartbeat.controller.heartbeat_controller::index
),但我会遵循建议并选择第一个选项。