PDO->bindParam, PDO->bindValue и PDO->closeCursor

До сих пор я использовал PDO->bindParam Однако, читая руководство, я нашел PDO->bindValue из того, что я могу сказать PDO->bindValue проходит по значению где как PDO->bindParam проходит по ссылке, это единственная разница?

$modThread = db()->prepare("UPDATE `threads` SET `modtime` = UNIX_TIMESTAMP( ) WHERE `threadid` =:id LIMIT 1");

while(something)
{
        $modThread->bindParam(':id', $thread);
        $modThread->execute();
//*******************HERE********************//
}

Снова, читая руководство, я нашел: PDO->closeCursor я должен поместить это, где отмечено? Это необязательно / автоматически вызывается? Кажется, это нужно только определенным водителям. Вызовет ли это драйвер, который не нуждается / не поддерживает его, приведет к ошибкам? Как насчет MySQL?

2 ответа

Решение

"Повторяющийся" bindParam() здесь не очень нужно:

$thread = 0;
$modThread->bindParam(':id', $thread);

while($thread < 20)
{
    $thread++;
    $modThread->execute(); //executing with the new value, which you couldn't do with bindValue
}

Вам не нужен closeCursor() когда нет результатов (т. е. только с SELECT или процедуры, возвращающие результаты), но обычно я уже выполнял fetchAll где-то в предыдущем выражении / строке.

Это не правда Если вам нужно использовать closeCursor, один из наиболее оптимальных вариантов - для команд вставки / обновления / удаления, и редко для операторов SELECT, для которых вы уже получили результаты.

Например, если вы выберете все записи из таблицы, а затем выполните $stmt->fetch(), это на самом деле сразу же решит задачу closeCursor, поскольку строки больше не находятся в невыполненном состоянии.

Из руководства:

Этот метод полезен для драйверов базы данных, которые не поддерживают выполнение объекта PDOStatement, когда ранее выполненный объект PDOStatement все еще имеет невыполненные строки. Если драйвер вашей базы данных страдает от этого ограничения, проблема может проявиться в ошибке из последовательности.

Когда вам действительно понадобится closeCursor, во время любого из следующих случаев:

  • Если ваш драйвер БД не разрешает выполнение нового stmt, в то время как невыполненные строки доступны из предыдущего выполнения
  • У вас есть несколько подготовленных операторов, и вы хотите выполнить их один за другим ($stmt1->execute(); $stmt->closeCursor(); $stmt2->execute(); $stmt2->closeCursor(); $stmt3... и т.д.)
  • У вас есть несколько stmts, которые должны выполнить вставку / обновление / удаление внутри одного блока. Это верно, потому что, хотя вы не получите обратно результаты строк mysql, вы ДОЛЖНЫ вернуть количество результатов для ряда затронутых строк (что все еще является результатом).
  • При использовании транзакций
  • Когда вы хотите выполнить подготовленные операторы в стиле выбора и выполнить их, но не извлекаете данные до тех пор, пока

Когда вам не нужен оператор closeCursor:

  • Если вы уже извлекли строки (как с $stmt->fetch()) до того, как будет выполнен ваш следующий оператор. В этот момент строки находятся в "извлеченном" состоянии и освобождают драйвер для выполнения новых операторов.

Так же полезно закрывать курсор - unset() (то есть: unset($stmt)) и установка для оператора значения null ($stmt = null), открывая двери для встроенного сборщика мусора, чтобы все очистить.

См. Руководство для получения дополнительной информации: http://php.net/manual/en/pdostatement.closecursor.php

Другие вопросы по тегам