196 votes

PHP/MySQL : Insertion d'une ligne et obtention de l'identifiant.

Le champ "id" de ma table augmente automatiquement lorsque j'insère une ligne. Je veux insérer une ligne et récupérer cet ID.

Je le ferais comme je l'ai dit, mais y a-t-il un moyen de le faire sans se soucier du temps entre l'insertion de la ligne et l'obtention de l'id ?

Je sais que je peux interroger la base de données pour trouver la ligne qui correspond aux informations saisies, mais il y a de fortes chances qu'il y ait des doublons, la seule différence étant l'identifiant.

259voto

cletus Points 276888
$link = mysqli_connect('127.0.0.1', 'my_user', 'my_pass', 'my_db');
mysqli_query($link, "INSERT INTO mytable (1, 2, 3, 'blah')");
$id = mysqli_insert_id($link);

Voir mysqli_insert_id() .

Quoi que vous fassiez, n'insérez pas et ensuite faites un " SELECT MAX(id) FROM mytable ". Comme vous le dites, c'est une condition de course et ce n'est pas nécessaire. mysqli_insert_id() dispose déjà de cette fonctionnalité.


Une autre solution serait d'exécuter les deux requêtes en une seule fois, et en utilisant MySQL 's LAST_INSERT_ID() où les deux tables sont modifiées en même temps (et PHP n'a pas besoin d'ID), comme :

mysqli_query($link, "INSERT INTO my_user_table ...;
  INSERT INTO my_other_table (`user_id`) VALUES (LAST_INSERT_ID())");

Note que chaque connexion garde la trace de l'ID séparément (ainsi, les conflits sont déjà évités).

59 votes

L'équivalent PDO est PDO::lastInsertId ( us3.php.net/manuel/fr/pdo.lastinsertid.php ).

0 votes

Le lien me conduit à la version russe de mysql_insert_id @php.net :P

11 votes

Cela fonctionne-t-il toujours s'il y a 10000 insertions asynchrones en même temps ?

40voto

soulmerge Points 37314

La fonction MySQL LAST_INSERT_ID() fait exactement ce dont vous avez besoin : il récupère l'identifiant qui a été inséré pendant cette session . Il est donc sûr à utiliser, même si d'autres processus (d'autres personnes appelant exactement le même script, par exemple) insèrent des valeurs dans la même table.

La fonction PHP mysql_insert_id() fait la même chose que d'appeler SELECT LAST_INSERT_ID() con mysql_query() .

2 votes

NB echo mysql_insert_id(); mysql_query('SELECT LAST_INSERT_ID(600)'); echo mysql_insert_id(); mysql_query('SELECT LAST_INSERT_ID()'); Le deuxième mysql_insert_id() ne reflète pas 600, alors que mysql_query('SELECT LAST_INSERT_ID()') volonté. Pour obtenir le mysql_insert_id() pour refléter le changement, vous devez d'abord faire une insertion ou une mise à jour (qui peut affecter 0 ligne). Voir le tout dernier paragraphe de : http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

29voto

NaturalBornCamper Points 829

Selon le site web de PHP, mysql_insert_id est maintenant déprécié et nous devons utiliser soit AOP o MySQLi (Voir Réponse de @Luke pour MySQLi). Pour ce faire avec PDO, procédez comme suit :

$db = new PDO('mysql:dbname=database;host=localhost', 'user', 'pass');
$statement = $db->prepare('INSERT INTO people(name, city) VALUES(:name, :city)');
$statement->execute([':name' => 'Bob', ':city' => 'Montreal']);

echo $db->lastInsertId();

4 votes

Nous avons la possibilité d'utiliser soit PDO o MySQLi (que je décris dans une autre réponse ici). Une bonne comparaison : code.tutsplus.com/tutorials/

22voto

Luke Points 1780

Comme l'a dit @NaturalBornCamper, mysql_insert_id est maintenant déprécié et devrait no être utilisé. Les options sont maintenant d'utiliser soit PDO soit mysqli. NaturalBornCamper a expliqué PDO dans sa réponse, donc je vais montrer comment faire avec MySQLi ( Amélioration de MySQL ) en utilisant mysqli_insert_id .

// First, connect to your database with the usual info...
$db = new mysqli($hostname, $username, $password, $databaseName);
// Let's assume we have a table called 'people' which has a column
// called 'people_id' which is the PK and is auto-incremented...
$db->query("INSERT INTO people (people_name) VALUES ('Mr. X')");
// We've now entered in a new row, which has automatically been 
// given a new people_id. We can get it simply with:
$lastInsertedPeopleId = $db->insert_id;
// OR
$lastInsertedPeopleId = mysqli_insert_id($db);

Consultez la documentation PHP pour plus d'exemples : http://php.net/manual/en/mysqli.insert-id.php

0 votes

Merci de l'avoir remarqué. Je préfère vraiment la notation par points de Javascript à la notation par flèches de PHP. :/

7voto

leMoisela Points 597

Je veux juste ajouter un petit détail concernant lastInsertId() ;

Lorsque vous saisissez plus d'une ligne à la fois, la dernière Id n'est pas retournée. mais le premier Id de la collection des derniers inserts.

Prenons l'exemple suivant

$sql = 'INSERT INTO my_table (varNumb,userid) VALUES
     (1, :userid),
     (2, :userid)';
$sql->addNewNames = $db->prepare($sql);
addNewNames->execute(array(':userid' => $userid));

echo $db->lastInsertId();

Ce qui se passe ici, c'est que je pousse dans my_table deux nouvelles rangées. L'id de la table est auto-incrémenté. Ici, pour le même utilisateur, j'ajoute deux rangées avec un différent varNumb .

La valeur renvoyée à la fin sera égale à l'identifiant de la ligne dans laquelle se trouve l'élément varNumb=1 ce qui signifie que ce n'est pas l'identifiant du dernier mais l'identifiant de la première ligne qui a été ajoutée lors de la dernière requête.

0 votes

S'en tenir à une seule opération à la fois - cela semble être la réponse générale pour toutes les méthodes utilisées, afin d'éviter des comportements inattendus

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X