1) Réinventer la roue

Une erreur classique lorsqu'on découvre un langage :
avoir tendance à tout réécrire soi-même au lieu d'utiliser les fonctions prévues à cet effet.
Deux conséquences à cela :


Vous souhaitez inverser une chaîne de caractères ? Calculer sa longueur ? Avant de foncer tête baissée dans des boucles "for" et autres variables temporaires, parcourez la documentation !
Php est un langage très riche en termes de fonctions, il est donc illusoire de connaître toutes celles qui sont disponibles dans tous les domaines, sans parler de leur syntaxe. La documentation est consultable en français ou téléchargeable sous différents formats sur le site de référence : Php.net
Avec une telle documentation, en quelques secondes, nous avons accès à "strrev"
et "strlen" deux fonctions qui ne pénaliseront pas les performances et nous feront gagner un temps de développement souvent précieux.

En utilisant des fonctions prévues par le langage pour ce que vous souhaitez faire, vous éviterez en plus à ceux qui reliront votre code de se demander pourquoi vous avez utilisé vos propres fonctions et pas celles qui sont déjà disponibles.
Il existe également de nombreux sites dédiés au Php sur le web tels que phpInfo.net (dont le forum est très actif) , PHPIndex.com... Citons également PHPBuilder, en anglais, qui offre un contenu très riche.
Enfin, pour les amateurs de newsgroups, vous trouverez sur fr.comp.infosystemes.www.auteurs.php de quoi vous dépanner en cas de problème. Ce newsgroup francophone est accessible via Foorum par exemple.

2) Oublier la convention de nommage

Lorsque vous programmez, pensez toujours à ceux qui consulteront votre code par la suite. Cela paraît évident dans le monde professionnel (turn-over, changements de mission), mais il est bon de l'appliquer chez soi aussi.
Il sera alors plus simple pour un programmeur tiers de rejoindre éventuellement le projet personnel que vous développez, ou de publier votre code par exemple.
A moins que vous ne souhaitiez "crypter" vos lignes de code avec un algorithme très personnel, il est conseillé d'utiliser une convention de nommage pour vos variables et autres fonctions.

Choisissez des noms ni trop longs : "$email_du_destinataire", ni trop courts : "$edd", mais par exemple (deux mots maximum) : "$email_dest".
Attention ! Le Php fait la différence entre "email_dest" et "Email_dest", il convient donc dès le départ de votre projet de définir comment les majuscules doivent être utilisées si besoin. Il ne faut évidemment pas changer d'avis en cours de route...
Si vous travaillez en équipe, rédigez pourquoi pas un document de référence auquel chaque membre se reportera pour nommer ses variables.
Vous pouvez choisir de faire commencer le nom de chaque variable transmise par URL comme ceci : "url_var", idem pour les formulaires "form_var", ainsi la provenance de la variable est connue sans même de notes explicatives au sein du code. Ce qui s'applique pour le nommage des variables, s'applique également au monde des fonctions. Pour elles, le choix d'un verbe est une bonne chose : "verifie_formulaire" ou pourquoi pas "check_form" si vous trouvez la version anglaise plus concise. A consulter également, la convention de nommage du Php group.

3) Ne pas commenter son code

A quoi bon commenter son code ? Après tout vous savez ce que vous faites non ? C'est une très mauvaise idée de concevoir la documentation de la sorte.
D'abord pour vous. L'algorithme qui vous semble évident aujourd'hui peut ne plus l'être du tout deux mois après.
Un grand classique...
Lorsque vous écrivez des scripts complexes, il est important de décrire ce que vous faites...
Mais pas n'importe comment.
<?
     // Affiche le nom de l'internaute et passe à la ligne
     echo("Votre nom : $nom<br>");
?>

Ce type de commentaire, sauf cas exceptionnel, n'a pas lieu d'être.
En tout cas pas sur un projet dont les développeurs sont des professionnels. Réservez vos commentaires pour des fonctions complexes ou des morceaux de code dont le fonctionnement n'est pas évident. Si vous connaissez JavaDoc, retrouvez son semblable dans le monde Php. PHPDoc peut en effet lui aussi générer de la documentation.
Enfin, dissociez le commentaire destiné à éclairer le lecteur sur le fonctionnement global d'une fonction (quelques mots placés avant la définition de la fonction suffisent), du commentaire, plus pointu, destiné à expliquer comment les choses se passent.
C'est la différence entre le "A quoi ca sert ?" et le "Comment ça fonctionne ?".

4) Utiliser " printf " à toute occasion

Nous parlions de mauvaises habitudes en introduction, voici un exemple où des programmeurs "C" peuvent être tentés d'utiliser la fonction "printf" à la place de la fonction "print". Sur la documentation on peut lire pour les fonctions "printf" et "print" respectivement "affiche une chaîne formatée" et "affiche une chaîne".
Cela signifie que "printf" ne doit être utilisée que lorsque la chaîne de caractères que l'on cherche à afficher contient des valeurs que l'on souhaite "formater", par exemple : Un euro, arrondi à 2 chiffres apres la virgule vaut :
<?
$euro = 6.55957; printf ("%.2f\n FF<br>", $euro); ?>

Par contre pour afficher...
Les membres de l'équipe sont :
<?
     $dev1 = "Anne-Sophie R.";
     $dev2 = "José F.";
     $dev3 = "Pierre GB";
     print("$dev1 $dev2 $dev3"); 
?>


... il faut utiliser "print" car il n'y a pas de chaînes à formater.
Rappelez-vous qu'avant d'afficher la chaîne de caractères, la fonction "printf " la formate systématiquement, ralentissant au passage l'exécution. La commande "echo" vous permet également d'afficher un résultat. Cette commande n'est cependant pas une fonction et ne peut donc pas être utilisée au sein d'une expression. En ce qui concerne la vitesse d'exécution, "echo" est en théorie plus rapide que "print", notamment parce qu'elle ne retourne pas de résultat.

5) Ne pas se limiter en variables temporaires

Selon vous, le code suivant est-il correct :
<?
// Recuperation des prix d'aujourd'hui :
$today = 20011113;
$req="select prix_fraise, prix_framboise, prix_pomme from prix_fruits
            where prix_date = $today";
$idreq=mysql_query($req,$idconnect);
// On admet que la connection s'effectue correctement et que la requête ne ramène
// qu'un seul tuple
$row=mysql_fetch_array($idreq)
$px_fraise = $row[prix_fraise];
$px_framboise = $row[prix_framboise];
$px_pomme = $row[prix_pomme];

echo("Prix des fraises : $px_fraise<br>");
echo("Prix des framboises : $px_framboise<br>");
echo("Prix des pommes: $px_pomme<br>"); 
?>
 


Syntaxiquement parlant, ce code est correct, le traitement sera effectué. Mais toutes nos variables nous sont-elles utiles ?
Si on considère ce programme comme complet, alors non, nous avons utilisé trois variables "temporaires" de trop,
et cela ralentit le traitement de notre programme.
25% de temps d'exécution supplémentaire, c'est ce que l'on risque si notre script Php comporte trop de variables temporaires. Il est donc intéressant de ne pas multiplier celles-ci inutilement.
Voyons comment s'en passer dans notre exemple : (Seule la partie modifiée est réécrite)
<?
$row=mysql_fetch_array($idreq)

echo("Prix des fraises : $row[prix_fraise]<br>");
echo("Prix des framboises : $row[prix_framboise]<br>");
echo("Prix des pommes: $row[prix_pomme]<br>"); 
?>

En règle générale, une variable temporaire est utile si elle contribue à améliorer la lisibilité de votre code (lorsqu'elle remplace une longue expression par exemple). De plus elle doit être utilisée au moins deux fois. Si aucune de ces deux conditions n'est réunie, c'est que vous n'en avez pas besoin !

6) Négliger la sécurité de son application

La sécurité est un vaste domaine et une affaire de spécialiste.
Etre exhaustif est donc hors de portée de cet article.
Rassurez-vous, tout n'est pas perdu pour autant.
En effet, entre tenter d'obtenir un système fiable à 100% et permettre à son site d'éviter certains écueils connus, il y a une différence de taille.
Nous évoquerons ici quelques-uns de ces dangers, et les moyens de les éviter.
"Prévoir le pire", voilà en résumé la conduite à adopter lors de la conception d'une application, écrite en Php ou non d'ailleurs.
Bien sûr, le niveau de sécurité requis et les conséquences d'un piratage ou d'une mauvaise action, parfois involontaire de la part d'un internaute, n'ont pas les mêmes conséquences sur un site de commerce électronique ou sur un site personnel. Toutefois, optimiser le site dont on s'occupe, personnel ou non, est une bonne chose.
Voyons où se situent certaines failles et comment y remédier.
Certaines étapes d'apparence anodine telle que l'inscription d'un internaute sur votre site, peuvent pourtant apporter leur lot de problèmes.
Si vous souhaitez par exemple recueillir l'adresse email d'un internaute avant de le laisser s'inscrire sur votre site, il se peut que celui-ci soit tenté de saisir une adresse invalide.
Que faire alors ? Vous pouvez toujours traiter la chaîne de caractères reçue grâce aux expressions régulières mais est-ce vraiment utile ? Au mieux vous détecterez que la syntaxe de l'email n'est pas correcte (pas de "@", pas de ".", etc) mais alors comment réagir face à un email syntaxiquement valide tel que :
toto@site-inconnu.com
Il reste à vérifier si le serveur existe ("socket validation"). Si celui-ci est temporairement en panne, vous rejettez l'email, pas de chance pour l'internaute...
Un internaute de perdu, dix de retrouvés pensez-vous ? Sans doute pas mais le problème n'est pas là.
Il existe un cas plus vicieux encore :
nom.connu@site-connu.com
Le site existe, le compte "nom.connu" aussi... Bien sûr, ça n'est pas l'email de l'internaute, mais il est valide.
Non, la seule solution vraiment fiable est de rallonger le processus d'inscription en obligeant l'internaute a cliquer sur un lien contenu dans un email que vous lui avez préalablement envoyé. Dans ce cas vous êtes sûr que celui-ci dispose d'un email et que c'est le sien (passons sur la mailbox familiale ou le compte piraté).
Rien ne vous dit par contre que ce n'est pas une de ces adresse "gratuites" créee pour l'occasion, mais qu'importe, vous avez votre email.
Convenons-en, ces problèmes d'emails ne mettent pas en péril la sécurité de votre application.
A la rigueur quelques "mailer-daemon" vous reviennent après l'envoi de votre newsletter, mais c'est tout.
Leur "intérêt" principal est en fait ailleurs : vous mettre la puce à l'oreille quant à la fiabilité du contenu renseigné par l'internaute.
Celui-ci peut en effet se revéler être plus dramatique qu'un email invalide.
Lorsque vous récupérez une variable renseignée par un internaute, vous pouvez utiliser la commande "escapeshellcmd" afin "d'échapper" tous les caractères susceptibles d'activer une commande Shell.
En d'autres termes cette commande place le caractère "\" devant chaque caractère potentiellement "dangereux" (#, &, ´, ', \, ", |, *, etc...).
Ce caractère n'est en effet pas ajouté automatiquement lorsque les chaînes de caractères sont stockées par Php, cela dépend notamment de l'utilisation de la variable "magic_quotes".
Un "phpinfo()" sur votre site vous indiquera si elle est activée ou pas.
Attention : si le Php est capable de stocker certaines données comprenant des caractères spéciaux, il n'en est pas forcément de même pour la base de données. L'utilisation de la fonction "addslahes" peut alors aider. Enfin, quelques règles simples sont à appliquer :
Ne pas transmettre de mot de passe en clair par URL ou formulaire.
Ceci est aussi valable pour des prix, ou d'autres informations sensibles.
Afin de limiter les problèmes de piratage (soumission d'un prix issu d'un autre domaine par exemple),
stockez ce type d'informations dans une base de données, effectuez les calculs du côté serveur (JavaScript ne suffit pas) !
De même, si l'utilisation de Javascript est souhaitable à des fins de vérification de formulaire (et éviter ainsi à l'internaute d'attendre la réponse du serveur), il faut systématiquement doubler tous les tests effectués du côté client par des traitements au moins équivalents du côté serveur. N'oubliez pas que JavaScript peut se désactiver... D'autres éléments à prendre en compte au niveau sécurité se trouvent sur le site officiel de Php.
Un autre article très intéressant est lui aussi à lire sur Phpbuilder.com.

7) "Copier / Coller" sans comprendre

A quoi bon s'appliquer à rendre son code Php le plus fiable et le plus propre possible si c'est pour inclure du code que vous ne maîtrisez pas dans votre application ? Télécharger des scripts sur Internet doit d'abord être un moyen de comprendre comment d'autres programmeurs ont résolu votre problème. Une fois le travail de compréhension effectué, les modifications éventuellement apportées, alors seulement vous pouvez inclure le code (Open) source dans le vôtre. Méfiez-vous des bouts de script qu'on croise parfois dans les forums de discussion, certains sont de vrais joyaux et sont fiables, d'autres ne vous apporteront peut-être que des ennuis ! Dans tous les cas il faut le comprendre, ne serait-ce que pour pouvoir maintenir par la suite votre application. Enfin, "patcher" son code sans réellement refondre le script téléchargé dans son application casse la logique qui était celle de votre script. Cela ralentit votre application Php et la rend moins lisible. Qu'en est-il en effet des conventions de nommage adoptées par l'auteur des lignes de code que vous souhaitez réutiliser ? Si vous n'y prenez garde vous risquez un conflit de variable qui risque de ne pas être évident à détecter. Bref, s'inspirer de la communauté et ne pas réinventer la roue, oui, mais à condition de comprendre comment elle tourne...

8) Ne pas gérer les erreurs éventuelles

Nous parlions tout à l'heure de sécurité, voici un type d'erreur qui peut conduire à des problèmes dans ce domaine.
Si l'erreur est parfois imprévisible, ne pensez pas qu'il soit pour autant impossible de l'intercepter.
S'il est en effet difficile de prévoir tout ce qui peut se passer sur un site, vous pouvez néanmoins vérifier que les résultats que vous obtenez sont cohérents et correspondent à vos attentes.
Si vous ne faites rien, vous exposez vos utilisateurs à des messages d'erreurs déjà parfois difficilement compréhensibles par un informaticien...
De plus, ces erreurs de script Php (parfois générés par la base de données) peuvent renseigner un pirate éventuel. Chaque bribe d'information récupérée peut constituer un point de départ pour un pirate : un message de debug que vous laissez affiché en cas de plantage, le type du SGBD, mieux encore le nom d'une table ou de la base...
Aussi, ces messages ne doivent pas apparaître sans un contrôle de votre part, c'est l'objectif de la gestion d'erreur ou "error handling".
Vous pouvez alors profiter des possibilités offertes par Php dans ce domaine (voir notre tutoriel) et indiquer à Php de remonter le maximum de "warning" possibles, un peu comme si vous descendiez la tolérance d'un compilateur. Pour cela, donnez la valeur "E_ALL" au "reporting level".
Afin de remonter le maximum d'erreurs, plusieurs éléments sont à tester : les connections aux bases de données, les valeurs retournées par les fonctions... Exemple :
$messerreur = "Veuillez nous excuser pour cet incident."; 
$req="select nom, prenom from membres where id = 2";
$idreq=mysql_query($req,$idconnect);
if ($idreq == 0)
{
     print "Erreur selection nom, prenom.<br>";
     echo("$messerreur<br>");
     mysql_close($idconnect);
     exit;
}
Si votre requête est invalide, le script s'arrête ici (afin d'éviter un plantage certain un peu plus loin) et affiche un message d'erreur particulier "sélection nom, prénom" avec en plus un message plus générique défini dans une bibliothèque par exemple (ici $messerreur).

9) Ne pas faire relire son code

Sans pour autant adopter des méthodes dignes de "l'eXtreme programming", faire relire votre code par un oeil extérieur est une très bonne chose. Qui n'a jamais passé de (trop) longues minutes, heures (?) autour de quelques lignes de code qui ne fonctionnaient pas, pour s'apercevoir au final qu'il ne s'agissait que d'une grossière erreur ?
Imaginez le temps gagné si vous aviez appelé un collègue à la rescousse...
Faire relire son code par quelqu'un qui n'a pas été impliqué dans son processus de production permet d'obtenir une toute autre vue que la sienne sur l'ensemble de la chose.
Des bugs peuvent ainsi être décelés bien plus rapidement que si c'est vous qui vous étiez relu.
C'est aussi l'occasion de revoir sa documentation si celle-ci est jugée peu lisible.

10) Négliger les bases de données

Optimiser son code Php ne sert à rien si c'est pour saccager la partie "bases de données".
Deux erreurs à éviter :

Lister toutes les mauvaises utilisations possibles des fonctions Php dédiées aux bases de données n'a pas de sens, alors un conseil : lorsque vous avez besoin d'une de ces fonctions, choisissez celle qui parmi la liste disponible (ici MySQL) est celle qui correspond le mieux à votre cas.
Inutile en effet de prendre un canon pour tuer une mouche.
Par exemple, n'utilisez pas "mysql_fetch_row" pour tester uniquement si votre requête a renvoyé des tuples mais plutôt "mysql_nums_row" qui est conçu pour cette tâche (si votre SGBD la supporte).
Trouvez la fonction minimale pour effectuer ce dont vous avez besoin.
Idem pour stocker les données issues d'une requête, n'inventez pas de système complexe de votre cru alors que "mysql_fetch_array" vous propose par exemple un tableau associatif très pratique :
$req="select nom, prenom from membres where id = 2";
$idreq=mysql_query($req,$idconnect);
// On passe sur les tests de validité de la requête ici... 
// La requête ne ramène qu'un seul tuple.
$row=mysql_fetch_array($idreq)
$nom_user = $row[nom];
$prenom_user = $row[prenom];

C'est lisible, court, que demander de plus ?
Passons au SQL...
Maîtriser ce langage, tout du moins ses bases, est très important. La rapidité de votre site en dépend.
Véritable cauchemar des hébergeurs mutualisés, la clause " SELECT * " appliquée sur une large table est une aberration lorsque l'on souhaite ne récupérer que quelques champs.
Rappatriez uniquement ce dont vous avez besoin !
Indiquez les champs, un par un, que vous souhaitez ramener.
Admettons que votre table "membres" ne comprenne que deux champs aujourd'hui : Nom et prénom.
Vous souhaitez récupérer les deux champs.
Un "SELECT * " ne fera effectivement pas de dégât... pour cette fois-ci.
Et si demain la structure de votre table change pour s'enrichir d'une dizaine de champ ?
Si vous ne modifiez pas votre SELECT, que vous auriez pu écrire correctement dès le départ, ce sont dix champs de trop que vous aller ramener...
De manière générale, le "SELECT * " est à proscrire, c'est une bonne habitude à prendre que de nommer, un par un, les champs dont vous avez besoin.
De même, utilisez la clause "WHERE" pour réduire encore le nombre de tuples à rappatrier de la base.
Inutile de d'abord tout ramener et de faire le tri en Php, par exemple dans la boucle "while" de l'exemple ci-dessus...
Utiliser des "if" pour identifier un enregistrement spécifique n'a pas lieu d'être quand on peut le ramener, seul, grâce à une clause WHERE.
Intéressez-vous à SQL si ça n'est pas encore le cas, il existe plusieurs tutoriels sur le web dédié à ce langage, en voici un où vous pouvez tester vos requêtes.