zf2 табличная функция как tablegateway/table
Как я могу использовать табличную функцию, как
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, но каким-то образом передать этот параметр с помощью символа подстановки?
Надеюсь, что это делает это более ясным
1 ответ
Если вы посмотрите на конструктор Zend\Db\TableGateway\TableGateway
класс, вы обнаружите, что этот класс принимает имя таблицы в качестве первого параметра.
Предположим, что имя вашей таблицы происходит из параметра GET с именем table. Таким образом, фабрика может выглядеть следующим образом.
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');
Короче говоря: используйте фабрику вместо анонимной функции, чтобы она была чистой и простой. Независимо от того, является ли фабрика или анонимная функция вызовом шлюза таблицы, принимает имя таблицы в качестве параметра в конструкторе. Так что просто получите имя таблицы из любого места и передайте его в качестве параметра.