mysql_query et UPDATE

DJ Gilles m’a contacté aujourd’hui concernant ce code PHP:

if(mysql_query("UPDATE mytable SET number=0 WHERE number=1")){
  print("Ok !"); // Résultat obtenu
}
else{
  print("Wrong !"); // Résultat attendu
}

La documentation sur mysql_query() dit ceci:

http://php.net/manual/fr/function.mysql-query.php

Pour les requêtes du type SELECT, SHOW, DESCRIBE, EXPLAIN et les autres requêtes retournant un jeu de résultats, mysql_query() retournera une ressource en cas de succès, ou FALSE en cas d’erreur.

Pour les autres types de requêtes, INSERT, UPDATE, DELETE, DROP, etc., mysql_query() retourne TRUE en cas de succès ou FALSE en cas d’erreur.

La ressource de résultat retournée doit être passée à la fonction mysql_fetch_array(), et les autres fonctions permettant d’explorer le résultat des tables, pour accéder aux données retournées.

Utilisez mysql_num_rows() pour trouver le nombre de lignes retournées pour une requête du type SELECT ou mysql_affected_rows() pour trouver le nombre de lignes affectées par les requêtes du type DELETE, INSERT, REPLACE, ou UPDATE.

mysql_query() échouera et retournera FALSE si l’utilisateur n’a pas les autorisations nécessaire pour accéder à la (aux) table(s) référencée(s) par la requête.

On est ici dans le cas d’un UPDATE et donc mysql_query() renvoit un false en cas d’erreur. Toutefois, le paragraphe ne précise pas si on peut considérer qu’il y a une erreur si aucune rangée n’a été affectée. Le dernier paragraphe indique bien qu’un false sera renvoyé si les autorisations sont insuffisantes mais ne précise pas s’il s’agit de l’unique cas de figure possible.

En pratique, le comportement de mysql_query() avec un UPDATE est de renvoyer true que des rangées aient été affectées ou pas et de renvoyer un false si la requête a échoué. Comme le sous-entends la documentation, on peut remplacer le code ci-dessus avec celui-ci:

$result = mysql_query("UPDATE mytable SET number=0 WHERE number=1");
 
$exists = mysql_affected_rows($result);
 
if( $exists == 0 ){
  print("Aucun changement");
} else {
  print("Un changement a été effectué");
}

En conclusion, on est tous passé par cette étape d’apprentissage où l’on arrivait pas à comprendre pourquoi du code ne fonctionnait pas comme attendu. En cas de doute, le premier réflexe à avoir est de lire la documentation sur les fonctions ou instructions au rôle décisif. Si la documentation n’est pas suffisamment claire, testez tous les cas de figures possibles pour voir les résultats. Ca peut prendre du temps mais aussi en faire gagner par la suite. La connaissance des nuances d’un langage vient naturellement avec l’expérience et vous pouvez accélérer le processus avec l’approche décrite dans cet article:

http://blog.developpez.com/james-poulson/p9809/java/pourquoi-tenir-un-journal-d-erreurs-est/

– James Poulson.