Search code examples
phpsymfonydoctrine-ormfosrestbundle

Symfony2 injecting Doctrine Dbal as service on constructor


Trying to pass a Doctrine dbal connection to my construct in a controller.

I am following this link to do it but it is not working:

How do you access Doctrine DBAL in a Symfony2 service class?

Here is my service inside app/config/config.yml

services:
 form1:
   class:       Test\TestBundle\Controller\FormController
   arguments:   [@doctrine.dbal.form1_connection]

Here is my controller with construct

namespace Test\TestBundle\Controller;

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\RestBundle\Util\Codes;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Doctrine\DBAL\Connection;


class FormController extends FOSRestController implements ClassResourceInterface
{

    private $connection;

    public function __construct(Connection $dbalConnection)  {
        $this->connection = $dbalConnection;    
    }
}

I get this error "message": "Catchable Fatal Error: Argument 1 passed to Test\TestBundle\Controller\FormController::__construct() must be an instance of Doctrine\DBAL\Connection, none given, called in /srv/test/tmp/dev/cache/classes.php on line 2449 and defined in /vagrant/test.com/src/Test/TestBundle/Controller/FormController.php

Here is app/config/routing.yml

test_form:
    pattern:  /api/v4/forms.{_format}
    defaults: { _controller: TestTestBundle:Form:cget, _format: json }
    requirements:
        _method: GET

Any help would be great. thx


Solution

  • Ok. The basic problem is that _controller: TestTestBundle:Form:cget does not use the service container to create the FormController. Hence no injection. You need to configure the controller as a service.

    http://symfony.com/doc/current/cookbook/controller/service.html

    Your routing will look like:

    test_form:
        pattern:  /api/v4/forms.{_format}
        defaults: { _controller: form1:cgetAction, _format: json }
        requirements:
            _method: GET
    

    However, this will create a second problem since your controller ends up extending from the Symfony base controller which requires the container to be injected as well. So you need to adjust your service file to something like:

    services:
        form1:
            class:       Test\TestBundle\Controller\FormController
            arguments:   ['@doctrine.dbal.form1_connection']
            calls:
                - [setContainer, ['@service_container']]
    

    I think that should get you going.