Des erreurs, il en existe de toutes sortes et c'est pour cela qu'il n'est pas facile de s'y retrouver pour un débutant.
Je ne pouvais pas faire une partie contenant TOUTES les erreurs SQL. Elles ne constituent pas une quantité infinie, mais certaines ne sont que très peu rencontrées et il serait inutile de toutes les retenir. Retenez les principales pour les corriger rapidement et ne pas buter sur une simple erreur alors que des lignes de code attendent d'être écrites.
À la connexion
Unknown MySQL server host 'locahlost'
Cette erreur apparaît quand MySQL ne trouve pas le serveur passé en premier paramètre de la fonction
mysql_connect(). Si vous êtes en local, il s'agit de
localhost. Sinon, c'est votre hébergeur qui vous donne le nom de son serveur MySQL. Notez ici la faute de frappe qui entraîne cette erreur.
Can't connect to MySQL server on 'localhost'
Cette fois-ci, le nom du serveur semble correct mais il est impossible de s'y connecter. Si vous êtes en local, vérifiez que le service « MySQL » est lancé, c'est-à-dire que l'icône de WAMP est blanche. Redémarrez WAMP pour en être sûr. Si vous êtes sur un hébergeur distant, vérifiez que l'hébergeur a ouvert votre compte et que le serveur MySQL n'a pas de problèmes ces temps-ci.
Access denied for user...
Ici, c'est le deuxième
et/ou le troisième paramètre de
mysql_connect qui est en cause. En local, il faut mettre
root et non pas de mot de passe, par défaut. Vous avez peut-être changé ces informations et dans ce cas, vous en connaissez les valeurs. Sur un hébergeur distant, là encore, c'est lui qui vous en informe à votre inscription.
À la sélection de la base de données
Unknown database 'monsit'
Vérifiez que le nom de la base de données, passé en paramètre à
mysql_select_db est correct. Notez ici la faute de frappe qui engendre cette erreur.
Lors d'une requête
C'est dans cette partie qu'elles sont les plus nombreuses. Des règles d'or régissent la création de requêtes afin d'en éliminer d'ores et déjà 80 %.
Tu nous sors encore ta baguette magique, et une fonction qui les enlève ?
Hélas, non ! Au risque de vous décevoir, cette fois-ci, c'est à vous de travailler.
On commence alors par les noms de tables et de champs.
Il ne faut pas entourer les noms de champs et de tables par des
backquotes (`), sauf s'ils font partie des mots réservés de MySQL. Vous en trouverez une liste
ici.
Quoi qu'il en soit, je ne vous conseille pas d'utiliser ces mots dans les noms de tables et de champs.
Si vous vous rappelez bien la structure donnée au premier paragraphe, vous ferez donc une requête du style :
Code : PHP | <?php
mysql_query('SELECT pseudo FROM membres') or exit('Erreur SQL ligne '.__LINE__.' : '.mysql_error());
?>
|
Voilà pour les noms de tables et de champs. Passons aux valeurs des champs (dans un
WHERE par exemple).
Chaque entrée provenant de l'utilisateur (par exemple dans un formulaire donc
$_GET ou
$_POST) doit passer par une fonction de sécurisation avant d'être insérée dans la base de données.
Les nombres entiers
Si le champ MySQL attend des
nombres entiers (de type
INT,
BIGINT...) :
intval() est votre ami !
Exemples tirés de la documentation :
Code : PHP | <?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('042'); // 42
echo intval('Toto a mangé 4 fruits'); // 0
echo intval('4Toto'); // 4
echo intval('u4u4u4o3'); // 0
?>
|
Vous voyez, elle retourne toujours un nombre entier et c'est ce que vous voulez.
De plus, dans une requête, ne mettez jamais de
quotes (ni doubles, ni simples, ni
backquotes) autour de la valeur d'un champ attendant des nombres entiers. Donc, par exemple :
Code : PHP | <?php
mysql_query('SELECT `pseudo` FROM `membres` WHERE `id` = '.intval($_GET['id'])) or exit('Erreur SQL ligne '.__LINE__.' : '.mysql_error());
?>
|
Les chaînes de caractères
Si le champ est de type
TEXT,
VARCHAR, MySQL n'attend pas forcément une valeur numérique, mais la plupart du temps une chaîne de caractères : on sécurise avec
mysql_real_escape_string().
Il faudra aussi la
délimiter par des guillemets simples (
simples quotes) « ' ».
En effet, sinon MySQL pourrait la confondre avec un champ. Imaginons qu'un membre s'appelle
mot_passe (pas très original...) :
Une requête du type :
Code : PHP | <?php
//$_POST['pseudo'] = 'mot_passe';
$pseudo = mysql_real_escape_string($_POST['pseudo']);
mysql_query('SELECT `email` FROM `membres` WHERE `pseudo` = '.$pseudo) or exit('Erreur SQL ligne '.__LINE__.' : '.mysql_error());
?>
|
Là, bien que la variable soit sécurisée, MySQL cherche les enregistrements où le champ
pseudo vaut la même chose que le champ
mot_passe (puisque par hasard, le champ
mot_passe existe) et c'est la catastrophe.
On entoure donc de guillemets :
Code : PHP | <?php
//$_POST['pseudo'] = 'mot_passe';
$pseudo = mysql_real_escape_string($_POST['pseudo']);
mysql_query("SELECT `email` FROM `membres` WHERE `pseudo` = '$pseudo'") or exit('Erreur SQL ligne '.__LINE__.' : '.mysql_error());
?>
|
Et voilà !
Outre les injections SQL que vous risquez de ne pas voir au premier coup d'œil, l'oubli de
mysql_real_escape_string peut vous causer un autre souci.
Imaginons que vous cherchiez l'adresse e-mail du membre
L'alter ego :
Code : PHP | <?php
//$_POST['pseudo'] = "L'alter ego";
mysql_query("SELECT `email` FROM `membres` WHERE `pseudo` = '$pseudo'") or exit('Erreur SQL ligne '.__LINE__.' : '.mysql_error());
?>
|
Une belle erreur SQL !
Regardons ce que vaut la requête et la coloration qui est faite :
Code : SQL | SELECT `email` FROM `membres` WHERE `pseudo` = 'L'alter ego'
|
Vous voyez ? Un carré rouge qui vous avertit qu'il y a un problème. En effet, dans une chaîne délimitée par des « ' », il y a un « ' » non échappé. Comme en PHP, cela génère une erreur. Avec
mysql_real_escape_string, la requête devient :
Code : SQL | SELECT `email` FROM `membres` WHERE `pseudo` = 'L\'alter ego'
|
Voilà qui est mieux, le fait qu'il y ait deux guillemets côte à côte sera interprété comme un échappement par MySQL : il n'en considèrera qu'un seul => parfait !
S'il y a une chose essentielle à se souvenir du tutoriel :
| Élément | Fonction de sécurisation | Délimité par |
|---|
| Nom de table |
Ø |
Ø |
| Nom de champ |
Ø |
Ø |
| Nombre entier |
intval() |
Ø |
| Chaîne de caractères |
mysql_real_escape_string() |
' |