Recently I made my first ZF2 application. I was walking through the code to see if I could make the code somewhat cleaner. Then I noticed that my controller classes have a huge block of code that supplies the controller of the TableGateway classes it needs. And I wondered is there a shorter/cleaner way to do this? It just seems silly that half of my controller class is dedicated to this simple task of fetching some TableGateWay classes.
protected $appointmentTable;
protected $customerTable;
protected $serviceTable;
protected $locationTable;
// ... some action methods that actually do the work.
public function getAppointmentTable()
{
if (!$this->appointmentTable) {
$sm = $this->getServiceLocator();
$this->appointmentTable = $sm->get('Appointment\Model\AppointmentTable');
}
return $this->appointmentTable;
}
public function getServiceTable()
{
if (!$this->serviceTable) {
$sm = $this->getServiceLocator();
$this->serviceTable = $sm->get('Appointment\Model\ServiceTable');
}
return $this->serviceTable;
}
public function getLocationTable()
{
if (!$this->locationTable) {
$sm = $this->getServiceLocator();
$this->locationTable = $sm->get('Appointment\Model\LocationTable');
}
return $this->locationTable;
}
public function getCustomerTable()
{
if (!$this->customerTable) {
$sm = $this->getServiceLocator();
$this->customerTable = $sm->get('Customer\Model\CustomerTable');
}
return $this->customerTable;
}
Could you just simplify the process in another method? I'm not aware of this function in Zend2, but still, if there is no method on framework level, you can write your own simplified method
My test so far:
Outputs:
So you can change
setTable()
method to use yourset()
proxy:Or you can get all your tables in array, iterate through it and pass the name to your
setTable()
method, which will set inner properties.My string test (because I don't have ZF2 right here, and testing if the proper string which you are passing to the
set()
proxy is built:Outputs:
Now all your
get____Table()
methods are valid getters. E.g.:returns
The way your Controllers should ideally be set up is through the means of proper(!) dependency injection. In Zend Framework 2 you have two main ways to declare controllers within the
ControllerManager
. The first one beinginvokables
for controllers who have no dependencies and the second one beingfactories
for controllers who have dependencies.Any
TableGateway
always is a dependency. To my experience there are no controllers who are invokables at all :PThere's two ways to set up controller factories.
Module.php
usinggetControllerConfig()
controllers[factories]
key in yourmodule.config.php
using Factory-ClassesFor simplicity I'll choose the first approach now:
With this, all that's left is for you to modify your controller and have it pass the respective tablegateway inside its constructor:
And that's all there is to it. It's all about proper dependency injection that makes your life ultimately so much easier.
Obviously this example only covers one table, but you can do the same just passing more tables through the constructor. That is: only if you really need ALL TableGateways in there (which sounds a bit fishy) ;)