Мы обновляем наше приложение до 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());
}
Я проверил ваш тестовый код на PHP 5.6.37 с помощью MariaDB 5.5.60, и я получаю этот ответ:
last_insert_id: 4
last_insert_id: 0
Поэтому это поведение не ограничивается PHP 7.2. И я не считаю поведение настолько странным, что после выполнения нового запроса в базе данных в драйвере PDO может случиться много чего.
Мое предложение было бы, и, возможно, это не то, что вы хотите услышать, чтобы всегда запрашивать последний идентификатор вставки сразу после вставки.
Возможно, это модуль php_pdo, который поставляется с PHP 5.6, потому что классический модуль mysql в PHP 5.6 сохраняет идентификатор последней вставки даже после оператора select.
Мы столкнулись с этой проблемой в PHP 7.2, потому что модуль mysql удален в этой версии, и, наконец, многие из нас выбирают pdo_module в качестве альтернативы.
Чтобы решить эту проблему, я назначил результат во временную переменную непосредственно после оператора вставки.