Marcin.ka Marcin.ka - 10 days ago 6
PHP Question

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

Answer

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.