I have a Zend Framework 3 MVC app with a controller with two end points. Both need to access the same class. It seems like the best way to do this would be to would be to make an instance of this class a property of the controller class like this:
class IndexController extends AbstractActionController
{
/**
* var Utility $utility
*/
protected $utility;
public function __construct(Utility $utility)
{
$this->utility = $utility;
}
public function indexAction()
{
$this->utility->doA('param1');
return new ViewModel();
}
public function otherAction()
{
$results = $this->utility->validateRequest($this->request);
if ($results)
{
return new ViewModel();
}
else
{
throw new Exception('Invalid request');
}
}
}
However, I don't know how to pass paramaters to the constructor since I don't know where Zend Framework "makes" it.
Zend Framework uses a concept called Dependency Injection. This is based on the D in SOLID, dependency inversion. Theory aside, you need to make a custom factory for your controller in modules.config.php. You also need to make a factory for the class calld Utility.
So first of all, you probably made your project with a command similar to
composer create-project -sdev zendframework/skeleton-application. If you did that you probably don't have the latest version of Service Manager. See if the filevendor/bin/generate-factory-for-classexists. If not, executecomposer update zendframework/zend-servicemanagerto add it there.Now lets make a factory for the utility class. Lets assume its in
module/Application/src/Service/Utility.phpand has the namespaceApplication\Service. You just typevendor/bin/generate-factory-for-class Application\\Service\\Utility > module/Application/src/Service/UtilityFactory.php. If you look in that file you can see:Now lets do the same for the controller with
vendor/bin/generate-factory-for-class Application\\Controller\\IndexController > module/Application/src/Controller/IndexControllerFactory.php. Open this factory and see its a little more complex.$containeris your dependency injection container. It executes the __invoke command in these factories when called.One more thing left to do. you need to edit your module.config.php. Replace the line
with
Now add the following section to the config:
Then your controller should work.