|
Pour notre projet, dans la suite de ce document, sera considéré comme "package" l'ensemble des classes et librairies de fonctions remis par un même groupe. Les noms de ces packages seront donc les suivants :
- Exercice - Sequence - Document - Etape - Carte |
- Lien |
Notre projet est destiné à être portable sur diverses stations de travail. Il doit donc se conformer à la norme XHTML 1.0 Transitionnal. Voici l'en-tête d'un fichier XHTML 1.0 :
<?xml version="1.0" encoding="ISO-8859-1"?> |
La majorité des pages seront réalisées en PHP. Leur extension sera toujours .php, et elles comporteront donc l'en-tête suivant :
<?php echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">"; ?> |
Il va de soi qu'il est interdit d'insérer le moindre script Javascript. Le DHTML est également déconseillé. PHP et Actionscript acceptés (heureusement). Les fichiers *.inc ne contiennent aucune procédure d'affichage!
Pour vérifier aisément que votre page est conforme à la W3C, vous pouvez la valider ou insérer cette image (Il suffit ensuite de cliquer dessus dans un navigateur pour être dirigé vers la validation de votre page) :
<p><a href="http://validator.w3.org/check/referer"> <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" width="88" height="31" border="0" align="right"/></a> </p> |
Toujours utiliser <?php ?> pour délimiter du code PHP, et non la version abrégée <? ?>. Cela est obligatoire pour être conforme aux règles de PEAR et c'est aussi la méthode la plus portable pour inclure du code PHP sur différents systèmes d'exploitations et configurations.
Les structures de contrôles incluent les 'if', 'for', 'while', 'switch', etc. Vous trouverez ici un exemple de structure 'if' qui est la plus compliquée :
if ((condition1) || (condition2)) { action1; } elseif ((condition3) && (condition4)) { action2; } else { defaultaction; } |
Les instructions de contrôle doivent avoir un espace entre le mot clé de l'instruction et la parenthèse ouvrante, afin de ne pas les confondre avec des appels de fonction.
Il est vivement recommandé de toujours utiliser des parenthèses, même dans les situations où elles sont techniquement optionnelles. Leur présence augmente la lisibilité du code et réduit le risque d'erreur logique lors de l'ajout de nouvelles lignes de code.
Pour l'instruction "switch" :
switch (condition) { case 1: action1; break; case 2: action2; break; default: defaultaction; break; } |
Petite astuce: Si vous désirez optimiser votre code, classez les "case" par fréquence d'apparition; le cas le plus fréquent en haut, et le moins fréquent en bas.
Concernant les expressions conditionnelles se composant d'une variable et d'une constante, la variable doit toujours être à droite (Cela évite de faire une affectation fâcheuse si l'on a oublié un '=').
if (CONSTANTE == $foo) { fooFoo(); } // est à préférer par rapport à: |
Un Magic number est un chiffre inclus dans une condition, tel que 3, 421, 12 qui apparaît dans une structure de contrôle... On ne sait pas ce qu'ils représentent. Dans l'exemple ci-dessous, que représentent 22, 19 et 16? Si les nombres vous semblent évidents le jour où vous programmez, qu'en est-il pour les autres ou vous même 3 jours plus tard? Que faire si ces valeurs viennent à changer?
if (22 == $foo) { commencerGuerreNucleaire(); } |
Pour ne pas programmer comme un amateur, il faut utiliser un nom réellement significatif, grâce à la commande define(). Cela est également valable pour 0 et 1.
define("WBUSH_AU_POUVOIR", "22"); |
Les fonctions doivent être appelées sans espace entre le nom de la fonction, la parenthèse ouvrante, et le premier paramètre; avec un espace entre la virgule et chaque paramètre; et aucun espace entre le dernier paramètre, la parenthèse fermante et le point virgule. Voici un exemple :
$var = foo($bar, $baz, $quux); |
Comme montré ci-dessus, il doit y avoir un espace de chaque côté du signe égal utilisé pour affecter la valeur de retour de la fonction à une variable. Dans le cas d'un bloc d'instructions similaire, des espaces supplémentaires peuvent être ajoutés pour améliorer la lisibilité :
$courte = foo($bar); $longue_variable = foo($baz); |
La déclaration des fonctions respecte l'indentation classique des parenthèses :
function fooFunction($arg1, $arg2 = '') { if (condition) { statement; } return $val; } |
Les arguments possédant des valeurs par défaut vont à la fin de la liste des arguments. Il faut toujours chercher à retourner une valeur ayant un sens lorsque cela est possible. Voici un exemple un peu plus long :
function connect(&$dsn, $persistent = false) { if (is_array($dsn)) { $dsninfo = &$dsn; } else { $dsninfo = DB::parseDSN($dsn); } if (!$dsninfo || !$dsninfo['phptype']) { return $this->raiseError(); } return true; } |
La documentation des classes incluse dans le code source doit suivre la convention PHPDoc, similaire à celle de Javadoc. Pour plus d'information au sujet de PHPDoc vous reporter à : http://www.phpdoc.de/
Les commentaires non inclus dans la documentation sont vivement encouragés. La règle générale est que, si en regardant une portion de code, vous pensez "Wououh, je ne veux pas me lancer dans cette explication", il faut absolument la commenter tout de suite avant que vous n'oubliez comment cela fonctionne.
Les commentaires du type C (/* */) et les commentaires standard C++ (//) sont tous les deux acceptés. Les commentaires de type Perl/shell (#) sont à éviter.
A chaque endroit où vous voulez inclure de façon inconditionnelle un fichier de classe, utilisez require_once(). A chaque endroit où vous voulez inclure de façon conditionnelle un fichier de classe (par exemple des méthodes de construction), utilisez include_once(). Ces deux méthodes s'assurent que le fichier classe n'est inclus qu'une seule fois. Elles partagent la même liste de fichiers, il est donc possible de les mélanger - un fichier inclus avec require_once() ne sera pas inclus une seconde fois par include_once(). Concernant la syntaxe, plusieurs possibilités existent; nous préférons que tout le monde utilise celle-ci:
include_once('exemple.php'); require_once('exemple.php'); |
Utilisez une indentation de 4 espaces, sans tabulation. Si vous utilisez Emacs pour éditer le code, vous devez fixer le paramètre indent-tabs-mode à 'nil'. Vous trouverez ici un exemple de configuration de Emacs pour respecter ces recommandations:
(defun php-mode-hook () (setq tab-width 4 c-basic-offset 4 c-hanging-comment-ender-p nil indent-tabs-mode (not (and (string-match "\.php$" (buffer-file-name)))))) |
Tout fichier de code source se trouvant dans le projet doit contenir le bloc de commentaires suivant comme en-tête : (ce qui est en italique est à modifier)
// +----------------------------------------------------------------------+ // | Projet ENGREF TT n°? Package ???? | // +----------------------------------------------------------------------+ // | Liste des fonctions: (pour un fichier include PHP) | // | - fonction1(...) | // | - fonction2(...) | // | | // | Page ?????: (nom de la page web) | // | rapide description en 1 ou 2 ligne | // | Date: DD-MM-YYYY | // +----------------------------------------------------------------------+ // | This file is subject to the terms of the GNU General Public License | // | as published by the Free Software Foundation. A copy of this license | // | is included with this software distribution in the file COPYING. | // | If you do not have a copy, you may obtain a copy by writing to the | // | Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | // +----------------------------------------------------------------------+ // | Copyright (c) 2003 | // +----------------------------------------------------------------------+ // |
Utiliser "exemple.com" pour tous les exemples d'URLs (RFC 2606).
Choisissez des noms ni trop longs : "$email_du_destinataire", ni
trop courts : "$edd", mais par exemple (deux mots maximum) : "$email_dest".
Attention ! Le Php est "case sensitive" ("email_dest"
!= "Email_dest")
Les classes doivent avoir un nom parlant. Eviter les abréviations lorsque cela est possible. Les noms de classes doivent toujours commencer par une majuscule. L'architecture hiérarchique des classes se retrouve aussi dans le nom de la classe, chaque niveau de la hiérarchie séparé par un trait souligné ( _ ). Voir la rubrique Package ci-dessus.
Les fonctions et les méthodes doivent être nommées en utilisant le style "studly caps". Les fonctions doivent avoir le nom du package comme préfixe, pour éviter les doublons entre les packages. La première lettre du nom (après le préfixe pour une fonction) est une minuscule, et chaque premier caractère d'un nouveau "mot" doit être une majuscule. Quelques exemples :
connect() obtenirDonnees() |
Les éléments (méthodes, attributs) privés d'une classe sont précédés d'un simple souligné (_) (ces éléments sont destinés à n'être utilisés que par la classe qui les déclare; PHP ne supportant pas encore le contrôle des noms privés). Par exemple :
_trier() _initialiserArbre() $this->_status |
Un nom de fonction doit suggérer une action (par un verbe : ex: "verifieFormulaire()" ). Les noms de variables doivent suggérer une propriété ou un nom (ex: hauteur, nom_utilisateur). De plus, les noms doivent toujours être prononçables. Nous fonctionnons à la française, c'est à dire que les fonctions set / get seront nommées fixer / obtenir.
Constantes |
Variables |
Variables Globales |
Les constantes doivent toujours être en majuscules, les mots séparés par des '_'. Préfixez les noms des constantes avec le nom en majuscule de la classe/package dans laquelle elle est utilisée. | Les variables doivent toujours être en minuscules, les mots séparés par des '_'. | Le recours aux variables globales devra être évité
au maximum ou justifié de manière très rigoureuse. Si votre package a besoin de définir des variables globales, leurs noms doivent commencer par un simple '_' suivi par le nom du package et un autre '_'. |
DB_CONSTANTE_DU_PACKAGE_DB |
$variable_a_gnico = "toto"; |
$_DB_variable_globale_du_package |
Les arguments dans les déclarations de fonction sont précédés d'un underscore. ex: $_nom_de_la_variable
function foo($_attribut1, $_attribut2, ...) |
Les effets de bords (modification de la valeur d'une variable) sur les variables globales est strictement interdit, il faut obligatoirement passer la variable globale en paramètre par référence de la fonction si elle doit être modifiée.
Enfin n'utilisez pas de mots ou abréviations toutes en majuscules:
Utilisez: getStatistiquesHtml() |
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 !
Autre possibilité: améliorer les performances de votre code en réalisant une seule fois une opération coûteuse au niveau temps d'exécution. Example:
<?php $max = filesize('myfile.dat'); for ($i = 0; $i < $max; $i++) { /*votre code*/ } ?> // est à préférer par rapport a <?php for ($i = 0; $i < filesize("myfile.dat"); $i++) { /*votre code*/ } ?> |
En effet, cela génère des warning lorsqu'on l'utilise avec des " " (magic quotes) :
$mon_tableau['foo-bar'] = 'Bonjour'; |
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 :<br> <? $euro = 6.55957; |
Par contre pour afficher...
Les membres de l'équipe sont : |
... 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.
Les chaînes contenues entre ' ne sont pas interprétées, mais affichées telles quelles. Si elle contient une variable, celle-ci ne sera pas remplacée. Lorsque l'on utilise les ", la chaîne est interprétée, c'est à dire que les variables seront remplacées par leur valeur lors de l'affichage. Les " sont donc plus lentes à l'exécution. Voir les exemples:
$world = World; print ('Hello $world'); // donnera Hello $world print ("Hello $world"); // donnera Hello World print ('Hello '.$world); // donnera Hello World |
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 :
- L'exécution du programme est ralentie.
- Votre code perd en lisibilité.
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 ! Manuel de référence PHP en version française ou Php.net
Si jamais vous pensez qu'une fonction que vous êtes en train de développer pourrait servir à d'autres personnes, n'hésitez pas à en faire une librairie, même petite!
Ne pas vérifier l'égalité du retour d'une fonction avec 1 (ou true). Il est préférable de tester l'inégalité par rapport à 0 (ou false). La plupart des fonctions retournent 0 si c'est faux, mais non-zéro si c'est vrai. Exemple:
if (false != foo()) {...} // est préférable à: if (true == foo()) {...} // la meilleure chose a faire reste: if ( foo() ) {...} |
Les tests contenant des égalités sont toujours perturbateurs: le programmeur a-t-il vraiment voulu faire cela? Parfois oui, mais souvent non. La solution est "Just not do it", l'inverse de la philosophie de Nike. A la place, utiliser des tests explicites, ne jamais faire de test implicite.
if ($abool = $bbool) { ... } // c'est confusant... //mieux vaut: $abool = $bbool; if ($abool) { ... } |
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:
string addslashes ( string str ) |
Concernant les formulaires, ne pas utiliser de champs cachés ("hidden"),
ne pas passer les mots de passe en clair dans l'URL!
Le Javascript étant formellement interdit (cf. Normalisation), si vous
avez besoin de tests de champs, ceux-ci doivent être exécutés
du côté serveur.
Une autre chose utile est de cacher les warning grâce à la commande
@ avant chacune des expressions qui pourrait provoquer un message d'erreur.
Un exemple: Si "fichier.php" ne peut être ouvert, les utilisateurs
liront:
WARNING: fopen('fichier.php, 'r') - No such file or directory in http://\www\yourdirectory\votrefichier.php
on line 28
En écrivant @fopen('fichier.php');
les messages d'erreurs
disparaissent.
! ATTENTION !
Dans la phase de développement, ces warnings peuvent être très
intéressants pour débugger votre code. Attention à ne mettre
les @ dans votre code trop tôt, surtout pas durant une phase de test.
D'autre part, les codes d'erreurs peuvent être récupérés
pour ensuite être traités et affichés (certaines erreurs
doivent être prévues et anticipées). Utilisez donc les @
avec discernement et seulement lorsque votre code est au point.
N'hésitez pas à faire relire votre code par une personne qui aura un oeil neuf sur le code que vous venez de produire. 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.
Les méthodes doivent se limiter au maximum à une page de code (cf Algorithmique).
Les possibilités d'optimisation de code PHP sont énormes. Pourquoi n'avons nous pas plus insisté sur ce point? Tout simplement car nous pensons qu'un programme fonctionnel est plus important que le gain de quelques millisecondes par instruction. Cependant, si vous désirez en savoir plus, voire optimiser votre code, n'hésitez pas à venir nous en parler. Nous disposons d'un grand nombre de publications et conseils sur ce sujet.
Ce document est issu du document original des consignes de codage de PEAR (http://pear.php.net/), d'un tutorial issu du site JDNetDeveloppeurs (http://developpeur.journaldunet.com/tutoriel/php/011113php_10erreurs.shtml) et d'une suite de documents dont voici la liste:
http://utvikler.start.no/code/php_coding_standard.html http://www.4webhelp.net/tutorials/php/coding_tips.php http://clue.denver.co.us/development/index6.html http://www.phpbuilder.com/columns/weerning20021209.php3?page=3 |
Si jamais vous pensez que nous vous avons copié un document dont vous êtes propritéaire et que vous ne figurez pas dans la liste, merci de nous le faire savoir pour que nous puissions rectifier cette erreur au plus vite. |
Voilà pourquoi leur document est une excellente base pour notre guide de développement. Bonne lecture!!!