zf2 表值函数作为 tablegateway/table

问题描述 投票:0回答:1

如何使用像

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

“pv_my_table_valued_function(?)”作为我的表网关的表

例如,正常的实例化是:

'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 对象,但以某种方式使用通配符传递该参数呢?

希望这能让事情变得更清楚

php zend-framework2 user-defined-functions
1个回答
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');

为了保持简短:使用工厂而不是匿名函数来保持干净和简单。无论是工厂还是匿名函数,表网关的调用都将您的表名称作为构造函数中的参数。因此,只需从任何地方获取表名称并将其作为参数传递即可。

© www.soinside.com 2019 - 2024. All rights reserved.