ZF2是否有一个较短/更清洁的方式来获得控制器中的TableGateway类?(ZF2 Is the

2019-10-19 13:18发布

最近我做了我的第一个应用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;
}

Answer 1:

你的控制器最好应设置的方式是通过适当的(!)依赖注入的手段。 在Zend框架2,你必须声明中的控制器主要有两种方式ControllerManager 。 第一个是invokables对谁没有依赖关系,第二个是控制器factories为谁具有相关的控制器。

任何TableGateway始终是一个依赖 。 我的经验有没有控制器谁是invokables都:P

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

  1. Module.php使用getControllerConfig()
  2. 根据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(这听起来有点腥);)



Answer 2:

你可能只是简化的另一种方法的过程中? 我不知道在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()方法是有效的干将。 例如:

var_dump($tables->getServiceTable());

回报

string 'Apointment\Model\ServiceTable' (length=29)


文章来源: ZF2 Is there a shorter/cleaner way to get the TableGateway classes in a controller?