insert_id
В этой статье рассматривается функция mysqli_insert_id() в PHP для получения ID, сгенерированного предыдущим запросом INSERT.
Когда вы вставляете строку в таблицу с первичным ключом AUTO_INCREMENT (или SERIAL), база данных генерирует новый ID автоматически. Функция mysqli_insert_id() позволяет считать это сгенерированное значение обратно в PHP сразу после вставки, чтобы использовать его как внешний ключ, вернуть в ответе API или перенаправить пользователя на новую запись.
В этой статье рассматривается, что возвращает mysqli_insert_id(), процедурный и объектно-ориентированный синтаксис, а также типичные ошибки, из-за которых функция возвращает неверное значение (или 0).
Что возвращает mysqli_insert_id()
mysqli_insert_id() возвращает ID, сгенерированный последним запросом, который выполнил вставку в столбец AUTO_INCREMENT, для данного соединения.
- Если предыдущий запрос сохранил значение в столбец
AUTO_INCREMENT, возвращается это значение. - Если предыдущий запрос не являлся
INSERT/UPDATE, затронувшим столбецAUTO_INCREMENT, возвращается0. - Значение привязано к текущему соединению, поэтому параллельные вставки от других клиентов никогда не влияют на результат. Это делает функцию безопасной даже на нагруженном сервере.
Примечание: значение отражает первый автоматически сгенерированный id оператора. Для одиночной вставки это id строки; для множественной вставки — id первой строки.
Синтаксис
mysqli_insert_id() принимает соединение MySQLi в качестве единственного аргумента:
int|string mysqli_insert_id(mysqli $mysql)В современном PHP (8.1+) при сбое запроса MySQLi выбрасывает исключение mysqli_sql_exception вместо возврата false, поэтому в примерах ниже предполагается, что ошибки будут проявляться в виде исключений.
Процедурный пример
Это наиболее распространённый стиль, который вы увидите в старых руководствах и кодовых базах:
<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");
mysqli_query(
$mysqli,
"INSERT INTO users (name, email) VALUES ('Ada', '[email protected]')"
);
$id = mysqli_insert_id($mysqli);
echo "Last inserted ID is: " . $id;
mysqli_close($mysqli);
?>Здесь мы открываем соединение с помощью mysqli_connect(), выполняем INSERT с помощью mysqli_query(), затем считываем сгенерированный id с помощью mysqli_insert_id() перед закрытием соединения.
Объектно-ориентированный пример
Та же логика с OOP-интерфейсом, который используется в большинстве нового кода. Сгенерированный id доступен через свойство insert_id:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
$mysqli->query(
"INSERT INTO users (name, email) VALUES ('Ada', '[email protected]')"
);
echo "Last inserted ID is: " . $mysqli->insert_id;
$mysqli->close();
?>Использование с подготовленными выражениями
В реальных приложениях вставку пользовательских данных следует выполнять через подготовленные выражения, чтобы избежать SQL-инъекций. ID вставки по-прежнему доступен после выполнения — как из объекта соединения, так и из объекта выражения:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
$name = "Grace";
$email = "[email protected]";
$stmt->execute();
echo "New user id: " . $stmt->insert_id; // same as $mysqli->insert_id here
$stmt->close();
$mysqli->close();
?>Типичные ошибки
- Считывайте значение немедленно. Значение отражает только последнюю вставку в данном соединении. Если до считывания выполнить другой
INSERT(даже в несвязанную таблицу), вы получите id той вставки. Сохраняйте значение в переменную сразу после вставки. - Отсутствие столбца
AUTO_INCREMENTдаёт0. Если первичный ключ таблицы задаётся вручную, ничего не генерируется, и функция возвращает0. UPDATEиSELECTобнуляют ожидания. УспешныйUPDATE, не затрагивающий столбец с автоинкрементом, или любойSELECTне создают нового сгенерированного id, и функция возвращает0.- При множественной вставке возвращается id первой строки. После
INSERT INTO t VALUES (...),(...),(...)вы получаете id первой вставленной строки; остальные следуют последовательно.
Связанные функции
mysqli_affected_rows()— сколько строк изменил последний запрос.mysqli_query()— выполняетINSERT, чей id вы считываете.- Обзор PHP MySQLi — полное расширение MySQLi.
- Вставка данных в MySQL — подробное руководство по вставке.
Заключение
mysqli_insert_id() — стандартный способ получить автоматически сгенерированный первичный ключ сразу после вставки. Считывайте его немедленно после INSERT, помните, что значение привязано к соединению (а значит, безопасно при параллельном выполнении), и ожидайте 0 всякий раз, когда последний оператор не генерировал значение автоинкремента.