最近我制作了我的第一个ZF2应用程序。我正在浏览代码,看看我是否可以使代码更清晰。然后我注意到我的控制器类有一大块代码,它们为所需的TableGateway类提供控制器。我想知道有更短/更清洁的方法吗?我的控制器类的一半专门用于获取一些TableGateWay类的简单任务,这似乎很愚蠢。
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;
}
答案 0 :(得分:2)
理想情况下,控制器的设置方式是通过正确的(!)依赖注入方式。在Zend Framework 2中,您有两种主要方法可以在ControllerManager
中声明控制器。对于没有依赖关系的控制器,第一个是invokables
,对于有依赖关系的控制器,第二个是factories
。
任何TableGateway
始终是依赖。根据我的经验,根本没有可以调用的控制器:P
设置控制器工厂有两种方法。
Module.php
使用getControllerConfig()
controllers[factories]
下的module.config.php
键下
醇>
为简单起见,我现在选择第一种方法:
public function getControllerConfig()
{
return array(
'factories' => array(
'My\Foo\Controller' => function ($cpm) {
//@var $cpm \Zend\Mvc\Controller\ControllerManager
$serviceLocator = $cpm->getServiceLocator();
$tableGateway = $serviceLocator->get('My\Table\Gateway');
return new \My\Foo\Controller($tableGateway);
}
)
);
}
有了这个,剩下的就是你修改你的控制器并让它在构造函数中传递相应的tablegateway:
class Controller
{
protected $tableGateway;
public function __construct(\My\Table\Gateway $tg)
{
$this->tableGateway = $tg;
}
public function indexAction()
{
return new ViewModel(array(
'entries' => $this->tableGateway->select()
));
}
}
这就是它的全部内容。所有关于适当的依赖注入都会让你的生活变得更加轻松。
显然,此示例仅涵盖一个表,但您可以通过构造函数传递更多表来执行相同的操作。那就是:只有你真的需要所有TableGateways(听起来有点可疑);)
答案 1 :(得分:0)
你能用另一种方法简化这个过程吗?我在Zend2中并不知道这个函数,但是,如果在框架级别没有方法,你可以编写自己的简化方法
到目前为止我的测试:
public function setTable($method) {
$method = lcfirst(str_replace("get", "", $method));
$this->$method = 'Apointment\Model\\'.ucfirst($method);
return $this->$method;
}
public function getLocationTable() {
$this->setTable(__FUNCTION__);
var_dump(get_object_vars($this));
}
输出:
array (size=1)
'locationTable' => string 'Apointment\Model\LocationTable' (length=30)
因此,您可以更改setTable()
方法以使用set()
代理:
public function setTable($method) {
$method = lcfirst(str_replace("get", "", $method));
if (!$this->$method) {
$sm = $this->getServiceLocator();
$this->$method = $sm->get('Apointment\Model\\'.ucfirst($method));
}
return $this->$method;
}
public function getLocationTable() {
return $this->setTable(__FUNCTION__);
}
public function getServiceTable() {
return $this->setTable(__FUNCTION__);
}
或者你可以在数组中获取所有表,迭代它并将名称传递给你的setTable()
方法,这将设置内部属性。
我的字符串测试(因为我不在这里使用ZF2,并测试是否构建了传递给set()
代理的正确字符串:
class Tables {
public function setTable($method) {
$method = lcfirst(str_replace("get", "", $method));
$this->$method = 'Apointment\Model\\'.ucfirst($method);
/*if (!$this->$method) {
$sm = $this->getServiceLocator();
$this->$method = $sm->get('Apointment\Model\\'.ucfirst($method));
}*/
return $this->$method;
}
public function getLocationTable() {
return $this->locationTable;
}
public function getServiceTable() {
return $this->serviceTable;
}
public function getAppointmentTable() {
return $this->appointmentTable;
}
public function setAllTables() {
foreach (get_class_methods(__CLASS__) as $method) {
if (strpos($method, 'get')!== false && strpos($method, 'Table')!==false)
$this->setTable($method);
}
}
}
$tables = new Tables();
$tables->setAllTables();
var_dump(get_object_vars(($tables)));
输出:
array (size=3)
'locationTable' => string 'Apointment\Model\LocationTable' (length=30)
'serviceTable' => string 'Apointment\Model\ServiceTable' (length=29)
'appointmentTable' => string 'Apointment\Model\AppointmentTable' (length=33)
现在,您的所有get____Table()
方法都是有效的getter。 E.g:
var_dump($tables->getServiceTable());
返回
string 'Apointment\Model\ServiceTable' (length=29)