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
"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?
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="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>
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="Acme\HeartbeatBundle\Controller\HeartbeatController::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 Acme\HeartbeatBundle\Controller;
use Acme\HeartbeatBundle\Service\HeartbeatService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class HeartbeatController extends AbstractController
{
public function __construct(HeartbeatService $hbs)
{
...
}
...
}
This is the Service/HeartbeatService.php
:
<?php
namespace Acme\HeartbeatBundle\Service;
class HeartbeatService
{
...
}
Could someone tell me what I'm doing wrong?
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
Or add an alias:
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.