PHP Conference Nagoya 2025

mysqli::$insert_id

mysqli_insert_id

(PHP 5, PHP 7, PHP 8)

mysqli::$insert_id -- mysqli_insert_idRetourne la valeur généré pour une colonne AUTO_INCREMENT par la dernière requête

Description

Style orienté objet

Style procédural

mysqli_insert_id(mysqli $mysql): int|string

Retourne l'ID généré par une requête INSERT ou UPDATE sur une table avec une colonne ayant l'attribut AUTO_INCREMENT. Dans le cas des requêtes multilignes INSERT, ceci retourne la première valeur automatiquement généré qui a été inséré avec succès.

Exécuter une requête INSERT ou UPDATE utilisant la fonction MySQL LAST_INSERT_ID() modifiera aussi la valeur retourné par mysqli_insert_id(). Si LAST_INSERT_ID(expr) a été utilisé pour générer la valeur de AUTO_INCREMENT, ceci retourne la valeur de la dernière expr à la place de la valeur généré de AUTO_INCREMENT.

Retourne 0 si la requête précédente n'a pas changé la valeur de AUTO_INCREMENT. mysqli_insert_id() doit être appelé immédiatement après que la requête ait généré la valeur.

Liste de paramètres

mysql

Seulement en style procédural : Un objet mysqli retourné par la fonction mysqli_connect() ou mysqli_init().

Valeurs de retour

La valeur du champ AUTO_INCREMENT modifiée par la dernière requête. Retourne zéro s'il n'y a pas eu de requête sur la connexion ou si la dernière requête n'a pas modifié la valeur de l'AUTO_INCREMENT.

Seul les requêtes émises par la connexion courante affecte la valeur de retour. La valeur n'est pas affecté par les requêtes utilisant d'autres connexions ou clients.

Note:

Si le nombre est plus grand que la valeur maximale d'un entier, elle sera retourné sous une chaîne de caractères

Exemples

Exemple #1 Exemple avec $mysqli->insert_id

Style orienté objet

<?php
mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$mysqli->query("CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
$mysqli->query($query);

printf("New record has ID %d.\n", $mysqli->insert_id);

/* drop table */
$mysqli->query("DROP TABLE myCity");
?>

Style procédural

<?php
mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

mysqli_query($link, "CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
mysqli_query($link, $query);

printf("New record has ID %d.\n", mysqli_insert_id($link));

/* drop table */
mysqli_query($link, "DROP TABLE myCity");
?>

Les exemples ci-dessus vont afficher :

New record has ID 1.
add a note

User Contributed Notes 9 notes

up
43
will at phpfever dot com
18 years ago
I have received many statements that the insert_id property has a bug because it "works sometimes". Keep in mind that when using the OOP approach, the actual instantiation of the mysqli class will hold the insert_id.

The following code will return nothing.
<?php
$mysqli
= new mysqli('host','user','pass','db');
if (
$result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")) {
echo
'The ID is: '.$result->insert_id;
}
?>

This is because the insert_id property doesn't belong to the result, but rather the actual mysqli class. This would work:

<?php
$mysqli
= new mysqli('host','user','pass','db');
if (
$result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")) {
echo
'The ID is: '.$mysqli->insert_id;
}
?>
up
16
mmulej at gmail dot com
3 years ago
There has been no examples with prepared statements yet.

```php
$u_name = "John Doe";
$u_email = "johndoe@example.com";

$stmt = $connection->prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
);
$stmt->bind_param('ss', $u_name, $u_email);
$stmt->execute();

echo $stmt->insert_id;
```

For UPDATE you simply change query string and binding parameters accordingly, the rest stays the same.

Of course the table needs to have AUTOINCREMENT PRIMARY KEY.
up
2
adrian dot nesse dot wiik at gmail dot com
1 year ago
If you try to INSERT a row using ON DUPLICATE KEY UPDATE, be aware that insert_id will not update if the ON DUPLICATE KEY UPDATE clause was triggered.

When you think about it, it's actually very logical since ON DUPLICATE KEY UPDATE is an UPDATE statement, and not an INSERT.

In a worst case scenario, if you're iterating over something and doing INSERTs while relying on insert_id in later code, you could be pointing at the wrong row on iterations where ON DUPLICATE KEY UPDATE is triggered!
up
6
bert at nospam thinc dot nl
16 years ago
Watch out for the oo-style use of $db->insert_id. When the insert_id exceeds 2^31 (2147483648) fetching the insert id renders a wrong, too large number. You better use the procedural mysqli_insert_id( $db ) instead.

[EDIT by danbrown AT php DOT net: This is another prime example of the limits of 32-bit signed integers.]
up
2
www dot wesley at gmail dot com
5 years ago
When using "INSERT ... ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)", the AUTO_INCREMENT will increase in an InnoDB table, but not in a MyISAM table.
up
5
Nick Baicoianu
17 years ago
When running extended inserts on a table with an AUTO_INCREMENT field, the value of mysqli_insert_id() will equal the value of the *first* row inserted, not the last, as you might expect.

<?
//mytable has an auto_increment field
$db->query("INSERT INTO mytable (field1,field2,field3) VALUES ('val1','val2','val3'),
('val1','val2','val3'),
('val1','val2','val3')");

echo $db->insert_id; //will echo the id of the FIRST row inserted
?>
up
0
jpage at chatterbox dot fyi
1 year ago
What is unclear is how concurrency control affects this function. When you make two successive calls to mysql where the result of the second depends on the first, another user may have done an insert in the meantime.

The documentation is silent on this, so I always determine the value of an auto increment before and after an insert to guard against this.
up
0
alan at commondream dot net
20 years ago
I was having problems with getting the inserted id, and did a bit of testing. It ended up that if you commit a transaction before getting the last inserted id, it returns 0 every time, but if you get the last inserted id before committing the transaction, you get the correct value.
up
-5
owenzx at gmail dot com
11 years ago
The example is lack of insert_id in multi_query. Here is my example:
Assuming you have a new test_db in mysql like this:

create database if not exists test_db;
use test_db;
create table user_info (_id serial, name varchar(100) not null);
create table house_info (_id serial, address varchar(100) not null);

Then you run a php file like this:

<?php
define
('SERVER', '127.0.01');
define('MYSQL_USER', 'your_user_name');
define('MYSQL_PASSWORD', 'your_password');

$db = new mysqli(SERVER, MYSQL_USER, MYSQL_PASSWORD, "test_db", 3306);
if (
$db->connect_errno)
echo
"create db failed, error is ", $db->connect_error;
else {
$sql = "insert into user_info "
. "(name) values "
. "('owen'), ('john'), ('lily')";
if (!
$result = $db->query($sql))
echo
"insert failed, error: ", $db->error;
else
echo
"last insert id in query is ", $db->insert_id, "\n";
$sql = "insert into user_info"
. "(name) values "
. "('jim');";
$sql .= "insert into house_info "
. "(address) values "
. "('shenyang')";
if (!
$db->multi_query($sql))
echo
"insert failed in multi_query, error: ", $db->error;
else {
echo
"last insert id in first multi_query is ", $db->insert_id, "\n";
if (
$db->more_results() && $db->next_result())
echo
"last insert id in second multi_query is ", $db->insert_id, "\n";
else
echo
"insert failed in multi_query, second query error is ", $db->error;
}
$db->close();
}
?>

You will get output like this:

last insert id in query is 1
last insert id in first multi_query is 4
last insert id in second multi_query is 1

Conclusion:
1 insert_id works in multi_query
2 insert_id is the first id mysql has used if you have insert multi values
To Top