ZF2是否有更短/更清晰的方法来获取控制器中的TableGateway类?

时间:2014-03-13 08:17:50

标签: php zend-framework2

最近我制作了我的第一个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;
}

2 个答案:

答案 0 :(得分:2)

理想情况下,控制器的设置方式是通过正确的(!)依赖注入方式。在Zend Framework 2中,您有两种主要方法可以在ControllerManager中声明控制器。对于没有依赖关系的控制器,第一个是invokables,对于有依赖关系的控制器,第二个是factories

任何TableGateway始终是依赖。根据我的经验,根本没有可以调用的控制器:P

设置控制器工厂有两种方法。

  1. Module.php使用getControllerConfig()
  2. 使用Factory-Classes
  3. 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)