2017-02-10 13 views
2

Я создал процедуру, в которой i выполняется два оператора select.Как вызвать PDOStatement :: nextRowset() в Cakephp 3

$stmt = $this->_connection->execute("CALL myFunction(:user_id)", [ 
    'user_id' => $userId 
]); 

Но когда я пытаюсь вызвать nextRowset(), как этого

$stmt->nextRowset(); 

Его дает мне ошибку

Призыв к неопределенному методу Ca \ Database \ Log \ LoggingStatement :: nextRowset()

Итак, мой вопрос: как я могу вызвать nextRowset() в Cakep л.с. 3

+0

Вы уверены, что '$ stmt' является pdoStmt? –

+0

@u_mulder Нет, это не так, как вы можете видеть из-за ошибки. Я не знаю, как в cakephp 3 получить pdostmt. –

+0

Вы не можете, если у вас нет собственной реализации StatementInterface. В основном вам нужно расширить PDOStatement торта, чтобы получить доступ к raw \ PDOStatement. –

ответ

2

Учитывая, что все основные классы заявление действительно расширить \Cake\Database\Statement\StatementDecorator в какой-то момент, вы можете добраться до базового родного \PDOStatement объекта через StatementDecorator::getInnerStatement(), как

while ($stmt instanceof StatementDecorator) { 
    $stmt = $stmt->getInnerStatement(); 
} 

if (!($stmt instanceof \PDOStatement)) { 
    throw new \RuntimeException('Expected an instance of \PDOStatement'); 
} 

Как уже упоминалось в комментариях, другой путь был бы реализовать свой собственный класс операторов (и заставить ваш код ожидать экземпляр этой конкретной реализации). Для совместимости с перекрестными DB вам нужно будет реализовать четыре разных оператора, плюс четыре драйвера, в которых вы бы повторно реализовали \Cake\Database\Driver::prepare(), так как здесь генерируются экземпляры операторов.

Кроме того, в случае, если вы хотите поддержать протоколирование запросов, вы должны создать пользовательский класс соединений и переопределить \Cake\Database\Connection::prepare() или \Cake\Database\Connection::_newLogger(), как это, где операторы, порождаемые водитель, завернутые в \Cake\Database\Log\LoggingStatement в случае запроса протоколирования включена ,

Я бы сказал, что если все, что вы хотите поддержать, это встроенные драйверы, то ожидающие \Cake\Database\Statement\StatementDecorator экземпляров, вероятно, лучший выбор на данный момент, хотя это не слишком приятно. Вы можете захотеть suggest adding functionality для продвижения операторов нескольких строк в качестве улучшения, но не уверены, что при этом будет много поддержки.

Смотрите также

+0

Спасибо, он работал. Могу ли я сделать это так: '(!($ stmt instanceof \ PDOStatement)) {$ stmt = $ stmt-> getInnerStatement(); } 'вместо исключения исключения –

+0

@AmanRawat Я бы не рекомендовал, чтобы это было менее безопасным, поскольку оно не проверяет, является ли' $ stmt' '' StatementDecorator'ом, то есть безопасно ли вызывать 'getInnerStatement()'. Конечно, вам не нужно бросать исключение, это был всего лишь пример, вы можете, конечно, выбрать менее инвазивную обработку ошибок, например, вернуть «false», показать флеш-сообщение и т. Д., Все зависит от контекста, d используйте этот код. – ndm

+0

Хорошо. благодаря –

 Смежные вопросы

  • Нет связанных вопросов^_^