Quand un script ajoute un enregistrement dans une table MySQL, il est parfois utile d’en mettre d’autres à jour. Et pour cela, on peut avoir besoin de récupérer le dernier identifiant d’auto-increment. La fonction PHP mysql_insert_id() le fera très bien… sous certaines conditions.
Petit rappel sur les connexions MySQL
Avant de faire l’opération, voici un petit rappel du comportement des connexions MySQL ouvertes par PHP.
La plupart du temps, la connexion avec MySQL est établie par la fonction PHP mysql_connect(). Si un deuxième appel est fait avec les mêmes arguments, la première connexion sera à nouveau utilisée. Le paramètre new_link modifie ce comportement et permet à mysql_connect() d’ouvrir à chaque fois une nouvelle connexion, même si mysql_connect() a été appelée avec les mêmes paramètres.
Lorsque le script utilise une connexion persistante (par la fonction PHP mysql_pconnect()), le comportement est le même, à deux différences (importantes !) près :
- Lors de la connexion, la fonction essaie de trouver une connexion persistante déjà ouverte, avec le même nom d’utilisateur et le même mot de passe. Dans ce cas, son identifiant est retourné sans ouvrir de nouvelle connexion.
- La connexion au serveur MySQL n’est pas coupée à la fin du script. Le lien est conservé pour un prochain accès, même si on utilise la fonction
mysql_close().
Au passage, notez que les connexions persitantes ne fonctionnent qu’avec PHP en version module.
Et l’auto-increment dans tout ça ?
L’auto-increment sera retourné par la fonction PHP mysql_insert_id(), mais il y a des risques de ne pas récupérer celui que vous attendez !
mysql_insert_id() retourne le dernier identifiant généré par un champ de type AUTO_INCREMENT, sur la connexion MySQL courante ou sur la connexion spécifiée par le paramètre link_identifier. Mais les surprises sont nombreuses :
- Si votre colonne
AUTO_INCREMENT est une colonne de type BIGINT, la valeur retournée par mysql_insert_id() sera incorrecte. À la place, il faut utiliser la fonction MySQL LAST_INSERT_ID() directement dans une requête SQL.
mysql_insert_id() ne fonctionne pas avec un REPLACE.
- Si vous utilisez dans votre requête SQL un
INSERT IGNORE en précisant un identifiant existant dans la table, l’enregistrement ne sera pas créé, ce qui est normal puisqu’il ne peut y avoir deux identifiants égaux. Par contre, mysql_insert_id() vous retournera l’auto-increment suivant, comme si l’enregistrement avait été ajouté !
- Si vous faites des insertions multiples (par exemple,
INSERT INTO table1 (champ1, champs2) SELECT champ1, champs2 FROM table2 WHERE champ1=2), mysql_insert_id() retournera l’identifiant du premier enregistrement ajouté !
J’arrête là le massacre car il y a bien d’autres cas. Pour s’en sortir, il faut privilégier la fonction MySQL LAST_INSERT_ID() (placée directement dans une requête SQL) et verrouiller la table :
mysql_query("LOCK TABLES table_exemple WRITE");
mysql_query("SET AUTOCOMMIT = 0");
mysql_query("INSERT INTO table_exemple (champ1, champ2) VALUES ('toto1','toto2')");
$mysql_id = mysql_query("SELECT LAST_INSERT_ID()");
mysql_query("COMMIT");
mysql_query("UNLOCK TABLES");