如何使用像
这样的表值函数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 对象,但以某种方式使用通配符传递该参数呢?
希望这能让事情变得更清楚
如果你看一下
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');
为了保持简短:使用工厂而不是匿名函数来保持干净和简单。无论是工厂还是匿名函数,表网关的调用都将您的表名称作为构造函数中的参数。因此,只需从任何地方获取表名称并将其作为参数传递即可。