PDO :: lastInsertId сбрасывается после SELECT в PHP 7.2

0

Мы обновляем наше приложение до PHP 7.2 (в настоящее время на 7.2.7) из PHP 5.5.9 и наткнулись на следующую проблему.

При выполнении запроса INSERT и немедленного запуска lastInsertId возвращаемое им значение является правильным. Но если запрос SELECT выполняется между ними, lastInsertId возвращает 0. Этого не произошло в PHP 5.5.9.

Наша версия MySQL - 5.7.22, но я не думаю, что это связано с тем, что у нас есть одна и та же версия MySQL на другой машине с PHP 5.5, и у нас нет этой проблемы.

Если вы запустите "SELECT LAST_INSERT_ID()"; как необработанный запрос (через PDO), результат, который вы получаете, является правильным, так что это, кажется, ошибка с PDO lastInsertId.

Вот пример фрагмента кода, который вы можете использовать для воспроизведения проблемы:

<?php

$username = "username";
$password = "password";    

$pdo = new PDO("mysql:host=127.0.0.1;port=3306;dbname=test_db", $username, $password);
    $pdo->query("CREATE TABLE IF NOT EXISTS 'test_table' (
      'id' int(11) NOT NULL AUTO_INCREMENT,
      'random_field' int(11) NOT NULL,
      PRIMARY KEY ('id')
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;");
    $st = $pdo->query("INSERT INTO test_table(random_field) VALUES (" . rand(1, 100000) . ")");
    if($st){
        echo "last_insert_id: " . $pdo->lastInsertId() . "\n";
        $pdo->query("SELECT 1 + 1");
        echo "last_insert_id: " . $pdo->lastInsertId() . "\n";
    }
    else{
        var_dump($pdo->errorInfo());
    }
  • 0
    Затем сохраните его в локальной переменной, это нормальное поведение.
  • 0
    Это определенно не «нормальное» поведение в том смысле, что: a) Раньше оно работало в PHP 5.5 (только что протестировано). Так это было "ненормально"? б) Как я уже сказал, если вы спросите MySQL напрямую (SELECT LAST_INSERT_ID ();), он даст вам правильный идентификатор. Таким образом, я ожидаю, что «нормальное» поведение PDO должно дать мне то же число, что и LAST_INSERT_ID () MySQL, а не другое.
Теги:
pdo

2 ответа

1

Я проверил ваш тестовый код на PHP 5.6.37 с помощью MariaDB 5.5.60, и я получаю этот ответ:

last_insert_id: 4 
last_insert_id: 0

Поэтому это поведение не ограничивается PHP 7.2. И я не считаю поведение настолько странным, что после выполнения нового запроса в базе данных в драйвере PDO может случиться много чего.

Мое предложение было бы, и, возможно, это не то, что вы хотите услышать, чтобы всегда запрашивать последний идентификатор вставки сразу после вставки.

  • 0
    Спасибо за ваш ответ. Я только что проверил снова с PHP 5.5.9, и он работает (я получаю один и тот же идентификатор оба раза). Так что, может быть, это изменилось с PHP 5.6 (или, скорее, модуль php_pdo, который поставляется с PHP 5.6)? Не знаю В любом случае, я не думаю, что это нормальное поведение, см. Мой ответ на @LawrenceCherone выше.
  • 0
    Я должен согласиться с вами, что в руководстве по PHP предполагается, что только новый INSERT изменит этот идентификатор, но он явно не указан. Он предупреждает вас о переменной природе результата в разных драйверах PDO. Учитывая, что, даже если это ошибка, она в настоящее время не работает так, как вы ожидаете, я вижу два решения: 1. Запросить идентификатор сразу после вставки или 2. Запросить MySQL напрямую. Это будет работать в любой версии PHP. На мой взгляд, первый вариант имеет больше смысла, он сохраняет вставку и получение продолжительного идентификатора вместе.
Показать ещё 1 комментарий
0

Возможно, это модуль php_pdo, который поставляется с PHP 5.6, потому что классический модуль mysql в PHP 5.6 сохраняет идентификатор последней вставки даже после оператора select.

Мы столкнулись с этой проблемой в PHP 7.2, потому что модуль mysql удален в этой версии, и, наконец, многие из нас выбирают pdo_module в качестве альтернативы.

Чтобы решить эту проблему, я назначил результат во временную переменную непосредственно после оператора вставки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню