zf2表值函数为tablegateway / table

时间:2018-05-02 20:51:31

标签: zend-framework2 user-defined-functions

如何使用像

这样的表值函数
select * from pv_my_table_valued_function(1)

“pv_my_table_valued_function(?)”作为我的tablegateway的表格

例如,正常的实例化将是:

'Application\Model\MyTable' =>  function($sm) {
     $tableGateway = $sm->get('MyTableGateway');
     $table = new MyTable($tableGateway);
     return $table;
},
'MyTableGateway' => function ($sm) {
      $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
      $resultSetPrototype = new ResultSet();
      $resultSetPrototype->setArrayObjectPrototype(new MyTableEntity());
      return new TableGateway('my_table', $dbAdapter, null, $resultSetPrototype);
},

我可以这样做,例如:

'MyTableValuedGateway' => function ($sm) {
          $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
          $resultSetPrototype = new ResultSet();
          $resultSetPrototype->setArrayObjectPrototype(new MyTableValued());
          return new TableGateway('pv_my_table_valued_function(?)', $dbAdapter, null, $resultSetPrototype);
    },

或者其他任何想法如何做,而不是稍后将Select对象转换为字符串并替换表名?

修改

作为我以后如何使用tableGateway的快速基本示例: 在我的模型MyTable.php

public function fetchAll()
{
    // I already initialized the tableGateway via Dependecy Injection in 
    // a __construct() in an abstract class
    $select = $this->tableGateway->getSql()->select();

    // some sql stuff
    $select->where(...);
    $select->order(...);

    // now it gets tricky.. what I normally do is known
    $resultSet = $this->tableGateway->selectWith($select);

    // what I need to do when using my table valued function is like
    $adapter = $this->tableGateway->getAdapter();
    $platform = $adapter->getPlatform();
    $sqlStr = $select->getSqlString($platform);

    $select = str_replace('FROM [my_table]', "FROM pv_my_table_valued_function({$this->my_special_parameter}) AS my_pv", $sqlStr);

    $resultSet = $adapter->query($select, array());

    return $resultSet;
}

那么我怎样才能“留下”Select对象,但是以某种方式通过通配符传递该参数?

希望这更清楚

1 个答案:

答案 0 :(得分:0)

如果你看一下Zend\Db\TableGateway\TableGateway类的构造函数,你会发现这个类将表名作为第一个参数。

我们猜测,您的表名来自名为table的GET参数。所以工厂看起来像下面的例子。

namespace Application\Db\TableGateway\Factory;

class MyDynamicTableFactory 
{
    public function __invoke(ContainerInterface $container)
    {
        // bc zf2 (remove when using zf3)
        $serviceLocator = $container->getServiceLocator();

        // table name from get parameter
        $router = $serviceLocator->get('router');
        $request = $serviceLocator->get('request');
        $match = $router->match($request);

        $table = $match->getParam('table');

        // adapter
        $adapter = $serviceLocator->get('Zend\Db\Adapter\Adapter');

        // resultset
        $resultset = new HydratingResultset(
            new ClassMethods(),
            new YourDynamicTableEntity()
        );

        // table gateway
        $gateway = new TableGateway($table, $adapter, null, $resultset);

        return $gateway;
    }
}

出于您的目的,工厂是最佳解决方案。即使您的表名来自GET参数以外的其他来源,您也可以在工厂中进行。只需实例化另一个类,它将为您提供表名。

只需在module.config.php文件的服务配置中编写工厂,如下所示......

'service_manager' => [
    'factories' => [
        'MyDynamicTable' => MyDynamicTableFactory::class,
    ],
],

使用此表示法,您可以在任何地方获得动态表网关,其中服务定位器可用。请记住,您不应该在控制器中调用服务定位器。只需通过依赖注入传递它,或者为你需要的每个类使用工厂。

工厂中表网关的示例调用

$gateway = $serviceLocator->get('MyDynamicTable');

为了保持简洁:使用工厂而不是匿名功能来保持其简洁。无论是工厂还是匿名函数,表网关的调用都将您的表名作为构造函数中的参数。所以只需从任何地方获取您的表名称并将其作为参数传递。