PDO готовят тихо сбои

Я экспериментирую с PHP's session_set_save_handler и я хотел бы использовать соединение PDO, чтобы хранить данные сессии.

У меня есть эта функция как обратный вызов для действий записи:

function _write($id, $data) {
    logger('_WRITE ' . $id . ' ' . $data);
    try {
        $access = time();
        $sql = 'REPLACE INTO sessions SET id=:id, access=:access, data=:data';
        logger('This is the last line in this function that appears in the log.');
        $stmt = $GLOBALS['db']->prepare($sql);
        logger('This never gets logged! :(');
        $stmt->bindParam(':id', $id, PDO::PARAM_STR);
        $stmt->bindParam(':access', $access, PDO::PARAM_INT);
        $stmt->bindParam(':data', $data, PDO::PARAM_STR);
        $stmt->execute();
        $stmt->closeCursor();
        return true;
    } catch (PDOException $e) {
        logger('This is never executed.');
        logger($e->getTraceAsString());
    }
}

Первые два сообщения журнала всегда обнаруживаются, но третье прямо после $stmt = $GLOBALS['db']->prepare($sql) никогда не добирается до файла журнала и нет никакой трассировки исключения также.

Таблица базы данных сессий остается пустой.

Сообщение журнала от _close обратный вызов всегда присутствует.

Вот то, как я соединяюсь с базой данных:

$db = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

У меня есть PHP 5.2.10.

Я пытался просто работать $GLOBALS['db']->exec($sql) с "вручную подготовленный" $sql содержание, но это все еще перестало работать тихо. Сам запрос в порядке, я смог выполнить его через консоль дб.


Править:

После того, как VolkerK определил проблему, я нашел эту статью, которая объясняет причину позади этого странные явления. Возможно, это могло быть информативно другим также.


2-е редактирование:

Наименее болезненное, волшебное решение состоит в том, что я должен был добавить ниже вызова функции к самому концу моего фронтального контроллера (основной index.php) файл:

session_write_close();

7
задан Wabbitseason 8 April 2010 в 22:04
поделиться

3 ответа

Мои ставки сделаны: $ GLOBALS ['db'] не установлен или не является экземпляром pdo (больше?) И поэтому PHP Неустранимая ошибка: происходит вызов функции-члена prepare () для объекта, не являющегося объектом , и php отключается.

$sql = 'REPLACE INTO sessions SET id=:id, access=:access, data=:data';
logger('This is the last line in this function that appears in the log.');
if ( !isset($GLOBALS['db']) ) {
  logger('there is no globals[db]');
  return;
}
else if ( !is_object($GLOBALS['db']) ) {
  logger('globals[db] is not an object');
  return;
}
else if ( !($GLOBALS['db'] instanceof PDO) ) {
  logger('globals[db] is not a PDO object');
  return;
}
else {
  logger('globals[db] seems ok');
}

$stmt = $GLOBALS['db']->prepare($sql);
logger('This never gets logged! :(');
4
ответ дан 7 December 2019 в 12:17
поделиться

Возможно, PDO не распознает синтаксис REPLACE INTO. Если базовая библиотека доступа к БД не поддерживает подготовленные операторы напрямую, PDO эмулирует их и может не иметь REPLACE INTO в своем списке возможных типов операторов.

Попробуйте проверить $ stmt-> errorCode () сразу после вызова подготовки?

Если это mysql, вы можете попробовать переписать подготовленный оператор следующим образом:

INSERT INTO sessions (id, access, data)
VALUES(:id, :access, :data)
ON DUPLICATE KEY UDPATE
    access=VALUES(access), data=VALUES(data);

и посмотреть, получится ли вы дальше.

1
ответ дан 7 December 2019 в 12:17
поделиться

Мне кажется, что к типам данных ресурсов нельзя получить доступ через $ GLOBALS [] . Что-то о том, как обрабатываются ссылки, или что-то в этом роде. Если вы хотите подшутить над моей догадкой, попробуйте следующее для объявления вашей функции:

function _write($id, $data) {
    global $db;
    logger('_WRITE ' . $id . ' ' . $data);
    try {

И вместо этого:

$stmt = $GLOBALS['db']->prepare($sql);

try

$stmt = $db->prepare($sql);

Вы также можете попробовать поймать старые добрые Exception вместо PDOException с; он может зацепиться за это.

Надеюсь, это поможет!

0
ответ дан 7 December 2019 в 12:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: