Является ли вызов PDOStatement:: closeCursor() необходимым, если объект оператора отключен?

Я использую PDO-соединение на основе Mysql с PDOStatement (::prepare(); ::execute()), и я использовал некоторый код от предыдущего разработчика, который использует PDOStatement::closeCursor() в методе.

В любом случае утверждение не будет отменено в конце функции:

public function fooBar($identifier)
{
    ...
    /** @var $dbc PDO */
    $dbc      = $conn->getConnection();
    $stmt     = $dbc->prepare('SELECT orderType, orderComment, payload FROM cart WHERE identifier = :identifier');
    $stmt->execute(array('identifier' => $identifier));

    $stmt->setFetchMode(PDO::FETCH_OBJ);
    $cart = $stmt->fetch();
    $stmt->closeCursor();

    ...

    return $result;
}

В моей ментальной модели я бы сказал, что PDOStatement здесь все равно очищается, так как я завершаю объект, чтобы позаботиться об этом домашнем хозяйстве (основы инкапсуляции). Поэтому вызов PDOStatement::closeCursor() выглядит для меня особенно полезным, поскольку это может быть не совсем то, что здесь нужно: поскольку оператор не должен использоваться повторно, мне вообще не нужно закрывать курсор.

side-note: этот код является образцовым, в реальном коде существует даже исключение, созданное после $stmt->execute(...), если количество строк не одно (1).

Существующий материал в Stackoverflow

Charles в мае 2011 г. в вопросе свободный результат:

Не просто некоторые драйверы - некоторые настройки, предоставляемые драйверами, требуют закрытия набора результатов перед отключением другого запроса, например, отключение MySQL PDO::MYSQL_ATTR_USE_BUFFERED_QUERY. К счастью, вы можете вызвать closeCursor, и он ничего не добьется, когда ему не нужно будет предпринимать действия. В противном случае просто отключите переменную, содержащую дескриптор инструкции, очистите.

Другой вопрос Когда я должен использовать closeCursor() для операторов PDO? не имеет принятого ответа, о котором я не задумываюсь, потому что все это очень опасно.

В Повторное использование инструкции PDO var завершает процесс, есть комментарий, сделанный, что отмена переменной не получить все ошибки (ошибки повреждения памяти):

[...] Я попытался отключить инструкцию var перед ее назначением, но это не помогло. [...]

Однако я не знаю, верно ли это для локальных переменных, масштаб которых не будет удален. Я также не использую mod_php как SAPI.

Связанный материал ошибки

Ответ 1

pdo_mysql_stmt_dtor() выполняет те же операции очистки, что и pdo_mysql_stmt_cursor_closer(), так как до тех пор, пока объект оператора либо явно не установлен, либо выходит за пределы области действия, операции всегда будут выполняться.

Поэтому не обязательно вызывать closeCursor(), если утверждение все равно будет уничтожено. Лично я бы сделал это в любом случае, поскольку мне нравится быть явным для удобочитаемости, но это сводится к личным стилистическим предпочтениям.

Основываясь на приведенных выше ссылках, это можно сказать только о PDO_mysql - для других драйверов это может быть недействительным.

Ответ 2

Мое понимание PDOStatement::closeCursor() заключается в том, что он очищает результат выполненного запроса. Но не влияет на PDOStatement вообще (просто результат его выполнения).

Из PHP Documnetation об этом методе:

освобождает соединение с сервером, чтобы другие операторы SQL могли быть выпущен

и

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

позвольте мне предположить, что вы должны сделать после каждого выполнения и выборки всех необходимых данных из текущего выполнения запроса вызова метода PDOStatement::closeCursor(). Я думаю, что драйвер MySQL для PDO делает это автоматически, но, похоже, есть проблемы с некоторыми драйверами, которые автоматически не освобождают результат.

Итак, если вы переключитесь на другой драйвер DB, который не освободит ожидающий результат запроса, вы столкнетесь с ошибкой.