0
votes

I have the following controller:

namespace Application\Controller;

use Application\Model\Person;
use Zend\Mvc\Controller\AbstractActionController;
use Application\Model\PersonTable;

class PersonController extends AbstractActionController
{
    private $table;

    public function __construct(PersonTable $table)
    {
        $this->table = $table;
    }
    // other methods
}

I tried to do injection by following documentation here:

https://docs.zendframework.com/tutorials/getting-started/database-and-models/

In module/Application/Module.php I added this function:

public function getControllerConfig()
    {
        return [
            'factories' => [
                Controller\PersonController::class => function($container) {
                    return new Controller\PersonController(
                        $container->get(Model\PersonTable::class)
                    );
                },
            ],
        ];
    }

In module/Application/config/module.config.php I modified this, so it would have my controller:

'controllers' => array(
        'invokables' => array(
            'Application\Controller\Index' => 'Application\Controller\IndexController',
            'Application\Controller\Person' => 'Application\Controller\PersonController'
        ),
    ),

I call the controller method from the console and get the error:

Catchable fatal error: Argument 1 passed to Application\Controller\PersonControl ler::__construct() must be an instance of Application\Controller\PersonTable, no ne given, called in E:\other\dropbox\Dropbox\programavimas\kodo pavyzdziai\htdoc s\zend_2_staff_register\vendor\zendframework\zendframework\library\Zend\ServiceM anager\AbstractPluginManager.php on line 170 and defined in E:\other\dropbox\Dro pbox\programavimas\kodo pavyzdziai\htdocs\zend_2_staff_register\module\Applicati on\src\Application\Controller\PersonController.php on line 12

Why it is not injecting?

1

1 Answers

1
votes

Because your declared your

'Application\Controller\Person' => 'Application\Controller\PersonController'

as a invokables class, you need to set it into the key : factories.

You did it this way :

public function getControllerConfig()
    {
        return [
            'factories' => [
                Controller\PersonController::class => function($container) {
                    return new Controller\PersonController(
                        $container->get(Model\PersonTable::class)
                    );
                },
            ],
        ];
    }

Config in Zf2 are merged so the PersonController is loaded by an invokables at the end and this code is become useless.

I advise you to create a object factory not an anonymous function and declared this :

    'controllers' => array(
            'invokables' => array(
                'Application\Controller\Index' => 'Application\Controller\IndexController',
            ),
            'factories' => array(
                'Application\Controller\Person' => 'Application\Factory\PersonControllerFactory'
            ),
        ),

Then this object PersonControllerFactory will return an instance of your controller with your correct dependancies.

Here an example of a controller's factory (not the same as service's factories) : https://github.com/Grafikart/BlogMVC/blob/master/ZendFramework2/module/Blog/src/Blog/Factory/PostControllerFactory.php

And its config line https://github.com/Grafikart/BlogMVC/blob/master/ZendFramework2/module/Blog/config/module.config.controllers.php#L8