Search code examples
phpzend-frameworkdependenciesfactoryzend-framework3

Zend 3 Factory Interface


I'm trying to implement Factory for my Controller:

class NumberControllerFactory implements FactoryInterface{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
    return new NumberController($container->get(Bar::class));
}

public function createService(ServiceLocatorInterface $services)
{
    return $this($services, NumberController::class);
}

}

I got error:

Fatal error: Declaration of Number\Factory\NumberControllerFactory::__invoke() must be compatible with Zend\ServiceManager\Factory\FactoryInterface::__invoke(Interop\Container\ContainerInterface $container, $requestedName, array $options = NULL) in C:\xampp\htdocs\MyProject\module\Number\src\Number\Factory\NumberControllerFactory.php on line 10

I need this, because I want to inject model to controller, because service manager has been removed from controllers in Zend 3.

I used skeleton described in https://framework.zend.com/manual/2.4/en/ref/installation.html

In composer.json is:

    "require": {
    "php": "^5.6 || ^7.0",
    "zendframework/zend-component-installer": "^1.0 || ^0.3 || ^1.0.0-dev@dev",
    "zendframework/zend-mvc": "^3.0.1",
    "zfcampus/zf-development-mode": "^3.0"
},

I don't understand this problem, I read a lot of tutorials, for example:

https://zendframework.github.io/zend-servicemanager/migration/

coould You help me, please?

I guess that currently this method is compatible with Zend\ServiceManager\Factory\FactoryInterface::__invoke


Solution

  • For injecting model into the controller, you need to create a factory class while configuration in module.config.php as below

     'controllers' => [
        'factories' => [
            Controller\AlbumController::class => Factory\AlbumControllerFactory::class,
        ],
     ],
    

    Here AlbumController is the controller class of Album module. After that you need to create a AlbumControllerFactory class inside the module\Album\src\Factory. In this class you need to write the code below:

      namespace Album\Factory;
    
      use Album\Controller\AlbumController;
      use Album\Model\AlbumTable;
      use Interop\Container\ContainerInterface;
      use Zend\ServiceManager\Factory\FactoryInterface;
    
    
      class AlbumControllerFactory implements FactoryInterface
      {
         public function __invoke(ContainerInterface $container,      $requestedName, array $options = null)
         {
          return new AlbumController($container->get(AlbumTable::class));
         }
      }
    

    You need to write the below code inside the controller class(AlbumController).

       public function __construct(AlbumTable $album) {
         $this->table = $album;
       }
    

    This way you can inject the model class into the controller class.