Single Factory for multiple Controllers?

zend-framework2

Solution

You could try attaching an initializer, then as the controller is created the instance is checked against known initializers. If the instance matches a given interface or abstract class, then you can apply some common logic.

I've not tested this approach with controllers but given that the ControllerLoader is a type of ServiceManager/ServiceLocator it should in theory work.

'controllers' => array (
    'initializers' => array(
        'MyApplication\Controller\Initializer'
    )
),

Then the Initalizer would look something like:

class Initializer implements InitializerInterface
{
    public function initialize($instance, ServiceLocatorInterface $serviceLocator)
    {
        if (!$instance instanceof MyControllerInterface)
        {
            return;
        }

        // Do something for this instance
    }
}

Problem

My question in short: Can I use a single Factory for multiple Controllers? More details: I have some global non-module specific settings in /config/autoload/global.php which look like this: ``` return array( 'settings' => array( 'setting_a' => 'foo', 'setting_b' => 'bar' ), // More ZF default configuration ... ); ``` Now I want to make these settings accessable in every controller without having to call `$this->getServiceLocator()->get('config')` all the time. So my idea was to introduce a class attribute `$settings` in my `AbstractController` which get’s injected with the configuration array. I tried to fetch the config directly in the constructor of `AbstractController`. However `getServiceLocator()` doesn’t seem ready at the time and returns NULL. I could build Controller Factories for every controller and inject the settings like this: ``` class ControllerFactory implements FactoryInterface { public function createService(ServiceLocatorInterface $serviceLocator) { $config = $serviceLocator->get('config'); return new \MyModule\Controller\MyController($config['settings']); } } ``` But it would be the same over and over again. So my question is: Can I use a single Factory for multiple controllers? In my module.config.php I could specify a single factory class for multiple controllers: ``` return array( 'controllers' => array( 'factories' => array( 'MyModule\Controller\MyControllerA' => 'MyModule\Factory\ControllerFactory', 'MyModule\Controller\MyControllerB' => 'MyModule\Factory\ControllerFactory', 'MyModule\Controller\MyControllerC' => 'MyModule\Factory\ControllerFactory', ) ), ); ``` But in the factory I need to return the actual Controller object by hand (see example above) which of course only works with one Factory per Controller. Hope, I made my problem clear. UPDATE 2013-03-24: Although I first followed the suggested solution by creating an initializer, I never really liked using it just for the injection of the configuration. So I kept digging around and ended up creating a Controller plugin to receive the settings. The code for the plugin looks like this: ``` use Zend\Mvc\Controller\Plugin\AbstractPlugin; class Settings extends AbstractPlugin { protected $settings; public function __invoke() { $config = $this->getController()->getServiceLocator()->get('Config'); if (isset($config['settings']) && is_array($config['settings'])) { $this->settings = $config['settings']; } return $this->settings; } } ``` After adding the plugin in module.config.php with ``` 'controller_plugins' => array( 'invokables' => array( 'settings' => 'My\Controller\Plugin\Settings', ) ), ``` I can easily access my settings within a controller by simply calling `$this->settings()`. Hope this helps anyone.

Original source