I’m a bit of a noob when it comes to Symfony. I am attempting to create a bundle with a controller that accepts a service as a constructor argument; however, I am receiving this error:
The controller for URI "/heartbeat" is not callable: Controller "AcmeHeartbeatBundleControllerHeartbeatController" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?
This is the 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="AcmeHeartbeatBundleServiceHeartbeatService"> <argument type="string" id="heartbeat.address"/> </service> <service id="acme_heartbeat.controller.heartbeat_controller" class="AcmeHeartbeatBundleControllerHeartbeatController"> <argument type="service" id="acme_heartbeat.service.heartbeat_service"/> <tag name="controller.service_arguments" /> </service> ... </services> </container>
This is the 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="AcmeHeartbeatBundleControllerHeartbeatController::heartbeat" methods="GET" /> </routes>
The main Symfony app’s config/routes.yaml
:
heartbeat: resource: '@AcmeHeartbeatBundle/Resources/config/routes.xml'
The Controller/HeartbeatController.php
:
<?php declare(strict_types=1); namespace AcmeHeartbeatBundleController; use AcmeHeartbeatBundleServiceHeartbeatService; use SymfonyBundleFrameworkBundleControllerAbstractController; class HeartbeatController extends AbstractController { public function __construct(HeartbeatService $hbs) { ... } ... }
This is the Service/HeartbeatService.php
:
<?php namespace AcmeHeartbeatBundleService; class HeartbeatService { ... }
Could someone tell me what I’m doing wrong?
Advertisement
Answer
Since Symfony 4, the preferred way of service naming is to use the FQCN as the service id in order to ease autowiring. You have used an old-style string id so even though the class matches, when Symfony looks it up by the expected id, it cannot find it.
It’s an easy fix, either change the definition to
<service id="AcmeHeartbeatBundleControllerHeartbeatController">
Or add an alias:
<service id="AcmeHeartbeatBundleControllerHeartbeatController" alias="acme_heartbeat.controller.heartbeat_controller" />
You could also change your route definition to the registered service id (acme_heartbeat.controller.heartbeat_controller::index
), but I’d follow the recommendations and go with the first option.