0

I have for example CategoriesController.php like this below

class CategoriesController
{
/**
 * Translator object.
 *
 * @var Translator $translator
 */
private $translator;

/**
 * Template engine.
 *
 * @var EngineInterface $templating
 */
private $templating;

/**
 * Session object.
 *
 * @var Session $session
 */
private $session;

/**
 * Routing object.
 *
 * @var RouterInterface $router
 */
private $router;

/**
 * Model object.
 *
 * @var ObjectRepository $model
 */
private $model;

/**
 * Form factory.
 *
 * @var FormFactory $formFactory
 */
private $formFactory;

/**
 * CategoriesController constructor.
 *
 * @param Translator $translator Translator
 * @param EngineInterface $templating Templating engine
 * @param Session $session Session
 * @param RouterInterface $router
 * @param ObjectRepository $model Model object
 * @param FormFactory $formFactory Form factory
 */
public function __construct(
    Translator $translator,
    EngineInterface $templating,
    Session $session,
    RouterInterface $router,
    ObjectRepository $model,
    FormFactory $formFactory
) {
    $this->translator = $translator;
    $this->templating = $templating;
    $this->session = $session;
    $this->router = $router;
    $this->model = $model;
    $this->formFactory = $formFactory;
}

/**
 * Index action.
 *
 * @return Response A Response instance
 */
public function indexAction()
{
    $categories = $this->model->findAll();
    return $this->templating->renderResponse(
        'AppBundle:Categories:index.html.twig',
        array('categories' => $categories)
    );
}

Classes like CategoriesControllel I have a lot, so I think part of it should be in one DefaultController, to not duplicate code. And if i move my code to DefaultController like this:

<?php
/**
 * Default controller class.
 */

namespace AppBundle\Controller;

/**
 * Class DefaultController.
 */
class DefaultController
{
/**
 * Translator object.
 *
 * @var Translator $translator
 */
private $translator;

/**
 * Template engine.
 *
 * @var EngineInterface $templating
 */
private $templating;

/**
 * Session object.
 *
 * @var Session $session
 */
private $session;

/**
 * Routing object.
 *
 * @var RouterInterface $router
 */
private $router;

/**
 * Model object.
 *
 * @var ObjectRepository $model
 */
private $model;

/**
 * Form factory.
 *
 * @var FormFactory $formFactory
 */
private $formFactory;

/**
 * CategoriesController constructor.
 *
 * @param Translator $translator Translator
 * @param EngineInterface $templating Templating engine
 * @param Session $session Session
 * @param RouterInterface $router
 * @param ObjectRepository $model Model object
 * @param FormFactory $formFactory Form factory
 */
public function __construct(
    Translator $translator,
    EngineInterface $templating,
    Session $session,
    RouterInterface $router,
    ObjectRepository $model,
    FormFactory $formFactory
) {
    $this->translator = $translator;
    $this->templating = $templating;
    $this->session = $session;
    $this->router = $router;
    $this->model = $model;
    $this->formFactory = $formFactory;
}
}

And in CategoriesController:

<?php
/**
 * Categories controller class.
 */

 namespace AppBundle\Controller;

 class CategoriesController extends DefaultController
 {

/**
 * Index action.
 *
 * @return Response A Response instance
 */
public function indexAction()
{
    $categories = $this->model->findAllWithAds();
    if (!$categories) {
        throw new NotFoundHttpException(
            $this->translator->trans('categories.messages.categories_not_found')
        );
    }
    return $this->templating->renderResponse(
        'AppBundle:Categories:index.html.twig',
        array('categories' => $categories)
    );
}

After it my application is broken.

( ! ) Catchable fatal error: Argument 1 passed to AppBundle\Controller\DefaultController::__construct() must be an instance of AppBundle\Controller\Translator, instance of...

When i leave empty constructor in CategoriesController, it didn't find any services in the form of private variables. How can I fix it?

  • 1
    First off, if the child class needs access to the properties in the parent class (like `$this->model` and `$this->translator`), they need to be set as `protected` (accessible for the parent and it's children). If they are set as `private`, only the parent class can access them. Secondly, it looks (by the part of the error message I can see), that you're injecting the wrong parameter to the constructor? – M. Eriksson Jun 21 '16 at 10:08
  • How are you instantiating the controller? – topher Jun 21 '16 at 10:13
  • ...and what @mickadoo said in his answer. You will probably need to register all controllers (children of DefaultController, like CategoriesController) in your service container. Not the parent (DefaultController). – M. Eriksson Jun 21 '16 at 10:14
  • I think you forgot to define namespace for Translator class ... -> use namespace_path_to_class/Translator; – pooler Jun 21 '16 at 13:38

1 Answers1

1

I think the problem is that you haven't registered your controller as a service in your services.yml. If you don't do that Symfony will treat is as a regular controller and try instantiate it with the default arguments, leading to the mismatch you saw in the error message.

Check the docs for how to define your controller as a service.

mickadoo
  • 3,337
  • 1
  • 25
  • 38
  • Then I'd check the other good suggestions that pooler and magnus-eriksson gave. I might also suggest type hinting with TranslatorInterface instead of a concrete class name. – mickadoo Jun 21 '16 at 15:59