Wikini

DiscussionsNormeDeCodagePHPPourWikiNi

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-98-80-143-34.compute-1.amazonaws.com
Cette page offre un lieu de discussion qui vise à formaliser nos Normes Et Recommandations De Developpement, sur l'aspect particulier du code PHP.

Candidats à la norme

Nous listons ici les items qui ont l'air de faire consensus et sont donc candidats à intégrer les normes de codage PHP pour WikiNi.
Il existe des règles indispensables pour des raisons de compatibilité ou autre, et des recommandations. Les recommandations sont fortement conseillées : tout développeur peut, sans discussion, les appliquer a posteriori sur un code qui ne les respecte pas.

Règles indispensables


Recommandations


Je propose de spécifier ici aussi qu'il est recommandé (je dirais même plus: indispensable !) de documenter toute portion de code, en respectant le modèle de phpDucumentor. -- LordFarquaad


Point de divergences


Formatage des blocs

Ce problème est assez important car :

1. Les blocs doivent être ouverts sur la même ligne. Inutile de mettre une nouvelle ligne avec juste pour une accolade ou une parenthèse ouvrante... (indent -br -ce)
ou 2. Les blocs sont ouverts sur une autre ligne (indent -bl -bli0 -nce) :
ou 3. (indent -br -nce) :

Pour résoudre ce problèmes on peut voir :

En fait, la 1 ne me convient vraiment pas pour les raisons suivantes :
Je suis d'accord sur la 3 même si je préfère toujours la 2.
Exemples montrant pourquoi j'aime bien 2 :
<?php

        
// underlinue
        
else if ($thing == "__")
        {
            static 
$underline 0;
            return (++
$underline "<u>" "</u>");
        }
        
// monospace
        
else if ($thing == "##")
        {
            static 
$monospace 0;
            return (++
$monospace "<tt>" "</tt>");
        }
        
// Deleted 
        
else if ($thing == "@@")
        {
            static 
$deleted 0;
            return (++
$deleted "<span class=\"del\">" "</span>");
        }
        
// Inserted
        
else if ($thing == "££")
        {
            static 
$inserted 0;
            return (++
$inserted "<span class=\"add\">" "</span>");
        }

?>

-- CharlesNepote

Pour les commentaires il y a toujours moyen de les placer à l'intérieur, je n'aime pas trop de détacher un else de son if, même par un commentaire...
Donc pour le code que tu donnes, ça donnerait (même si l'idéal serait d'utiliser un switch tout de même...):
<?php
        
elseif ($thing == "__") { // commentaire ici
            
static $underline 0;
            return (++
$underline "<u>" "</u>");
        } elseif (
$thing == "##") {
            
// ou alors là
            
static $monospace 0;
            return (++
$monospace "<tt>" "</tt>");
        } elseif (
$thing == "@@") {
            
/*
            * Ou même comme ceci,
            * en plusieurs lignes
            */
            
static $deleted 0;
            return (++
$deleted "<span class=\"del\">" "</span>");
        } elseif (
$thing == "££") { // Inserted
            
static $inserted 0;
            return (++
$inserted "<span class=\"add\">" "</span>");
        }
?>

Par contre pour les deux problèmes que tu mets en avant au sujet de certains logiciels, j'imagine qu'ils sont inévitables... (du moins pour le pliage/dépliage) Est-ce si grave ?
-- LordFarquaad

Franchement, quand on regarde les deux fenêtres ci-dessus, je trouve vraiment qu'il n'y a pas photo ! La première fenêtre contient un code très lisible où chaque bloc est clairement séparé, un commentaire annonçant clairement le contenu de chaque bloc. La deuxième me paraît très fouillie et inélégante. D'autres auteurs vont dans mon sens : Either form is acceptable, many people, however, find the first form more pleasant. Why is the topic of many psychological studies.
There are more reasons than psychological for preferring the first style. If you use an editor (such as vi) that supports brace matching, the first is a much better style. Why? Let's say you have a large block of code and want to know where the block ends. You move to the first brace hit a key and the editor finds the matching brace.
(source).
Hormis l'argument des outils gérant mieux les solutions 2 et 3, il y a aussi le poids de l'existant : je ne vois nulle part dans WikiNi l'utilisation de la solution 1 : il y aurrait beaucoup de code à refaire à la main puisqu'il faudrait déplacer beaucoup de commentaires. Ce qui me conduit imanquablement au troisième argument massue ;) : les solutions 2 et 3 se prettent bien à l'indentation automatique alors que cela devient impossible dans le cas de la solution 1 (à cause des commentaires). A la rigueur je veux bien accepter la 3. Cela dit, je m'inclinerai s'il existe des contre-arguments et une majorité pro-1. -- CharlesNepote

Pour moi les deux exemples sont aussi clairs l'un que l'autre, sauf que le deuxième est beaucoup plus court pour faire la même chose...
Je ne comprends pas trop l'histoire des accolades correspondantes: trouver l'accolade fermante d'une ouvrante n'est pas un question d'indentation mais de comptage correct des accolades imbriquées :-s D'ailleurs la plupart des ide repèrent correctement cela, quelque soit l'indentation...
Enfin, apparemment comme tu dis beaucoup d'outils gèrent mieux les solutions 2 et 3 (le CodeBeautifier de PhpEdit? ne semble pourtant gérer que les 1 et 2 lui tiens) ce qui me parait en effet être un gros avantage pour que la norme ne soit pas (trop) contraignante.
Par contre pour ce qui est de l'utilisation des diverses solutions dans WikiNi, c'est pas tout à fait vrai ce que tu dis... La solution 2 semble certes beaucoup utilisée, mais rien que dans wakka.php on trouve un peu de tout:
Quand tu dis que les solutions 2 et 3 se prettent mieux à l'indentation automatique à cause des commentaires, tu veux dire pour passer de l'une à l'autre ?
Finalement, vu les arguments que tu donnes (et que la 3 ne semble pas gérée par phpedit), je suis d'accord pour la 2. Reste à voir ce que les autres en pensent. L'important pour moi c'est de décider rapidement d'un bon standard commun, afin que les prochaines développements le respectent directement. Ceci est d'ailleurs valable également pour la documentation... (c'est vraiment dommage que nous ne soyons que trois à participer à cette discussion qui est tout de même à l'échelle de tous les développeurs, y compris ceux qui ne font pas partie de l'équipe de développement mais voulant voir leurs contributions intégrées à WikiNi...) -- LordFarquaad

Finalement j'adopte le modèle n°2. Au début ça fait bizarre mais on finit par en apprécier rapidement la clarté. Il faudra juste déterminer quelle présentation il faut utiliser pour les commentaires desinstructions condiftionnelles et des boucles (avant le if, else etc. / en fin de ligne, / entre le if, else etc. et l'accolade ouvrante / sur la même ligne que l'accolade ouvrante...)
Je pense qu'on peut commencer à rédiger une page NormeDeCodagePHPPourWikiNi? avec les résultats des discussions, afin d'y voir un peu plus clair là-dedans. -- LordFarquaad

Notes :
On peut automatiser l'indentation d'un fichier avec la commande indent sous GNU/Linux.
Je propose d'utiliser les options de indent pour spécifier notre norme de façon rapide et non-ambiguë.
Voir aussi le manuel de indent et indent pour Windows.
-- ProgFou

Sur le principe, je suis d'accord pour utiliser un automatisme pour indenter. Quelques remarques :
-- CharlesNepote

Commentaires

Personnellement j'aime bien de les mettre à l'intérieur des instructions conditionnelles, et précéder celles-ci d'une explication de ce qu'on veut faire, par exemple (je me force pour les blocs lol):
<?php
// vérifions le nombre de pattes de notre animal
if($nbDePattes 8)
// mille-pattes
    
echo 'Cet animal est un myriapodes';
}
elseif (
$nbDePattes == 8)
// arraignée, crustacé
    
echo 'Il s\'agit d\'une arraignée ou d\'un crustacé';
}
elseif (
$nbDePattes == 6)
// insecte
    
echo 'Ceci est un insecte';
}
elseif (
$nbDePattes == 4)
// mammifères, reptiles
    
echo 'Un animal à quatre pattes, probablement un mammifères ou un reptile';
}
elseif (
$nbDePattes == 2)
// singes, oiseaux... humains
    // a-t-il des ailes ?
    
if (nbAiles)
    { 
// oiseaux
        
echo 'C\'est un oiseau';
    }
    else
    { 
// autres
        
echo 'Ceci est un humain ou un singe';
    }
}
elseif (!
$nbDePattes)
// rampant, poisson
    
echo 'Ceci est un animal rampant ou alors un poisson';
}
else
// 1, 3, 5 ou 7 pattes
    
echo 'Mmm un animal très étrange qui provient certainement de p3x972 !';
}
?>
Bon évidemment c'est un exemple simpliste où les commentaires sont un peu redondants, mais je trouve plus logique de dire d'abord ce qu'on veut faire ou vérifier, et ensuite que les descriptions des différents cas se fassent là où ces cas sont rencontrés. En mettant un commentaire juste avant un else, il se retrouve placé à la fin d'un if (ou elseif), c'est à dire à un point où aucune instruction ne peut se trouver, donc en quelque sorte il commente un point inatteignable (même si on le comprend) et marque un détachement entre les if et les else que je trouve assez perturbant. Ceci a certes moins d'importance à mes yeux que la structure des blocs de code mais je pense qu'il faudrait tout de même officialiser une norme quant aux commentaires. (notemment les met-on sur la même ligne que l'instruction, ou sur la ligne qui précède ?)
Il me semble qu'actuellement les commentaires précédènt en général ce à quoi ils s'appliquent, que ce soit des instructions, des conditions, des boucles ou les différents cas d'un switch. Pour moi ça peut être conservé ainsi, même si je préfère faire autrement dans le cas des if-elseif-else... -- LordFarquaad

Documentation

La discussion a été lancée dans ModeleObjetDeWikiNi. Pour moi le modèle des phpDocumentor est vraiment très bon et tend à se standardiser, je propose qu'on se mette à l'appliquer dès à présent. -- LordFarquaad


Préférences de chaque développeur

Pour mémoire, j'utilise comme éditeur : principalement Scite (Win et Linux), parfois Jedit, parfois Dreamweaver, parfois Kate et je découvre PHPEclipse qui m'a l'air très prometteur.
Pour ma part, j'apprécie :

<?php

// -- Traitements --------------------------------------------
//
// [du code]



// -- Présentation -------------------------------------------
//
echo "<h1>Mon code HTML</h1>\n";
if (isset(
$_REQUEST['test'])
{
    echo 
"ok\n";
}
else
{
    echo 
"zut\n";
}



// -- Partie relative aux fonctions ----------------------------
//
function TestTest ($tutu$toto)
{
    
// du code
    
echo "<a href=\"".$url."\">".$url."</a>".$matches[2];
    
//
    
echo "<a href=\"" $url "\">" $url "</a>" $matches[2];
}


Evidemment, je suis ouvert à toute autre norme. N'hésitez pas à indiquer vos préférences en expliquant. On essaiera de dégager un consensus...
-- CharlesNepote

Plutôt que de dire ce qui me plait ou non dans ta syntaxe, je vais détailler la mienne, comme ça on pourra plus facilement comparer après:
  1. Limiter la longueur des lignes : toute ligne devrait apparaître entièrement avec une résolution de 1024 en largeur et des tailles de police "normales". (Ceci doit faire à peu près 100 à 120 carractères)
  2. Aucun espace ne précède une virgule ou un point-virgule
  3. Une virgule ou un point-virgule est toujours suivi d'un espace, ex:
    • $pos = strpos('u', 'bonjour à tous, 10);
    • for($i = 0; $i < 10; $i++) {
      • echo $i;
    • }
  4. Après un point-virgule, on revient toujours à la ligne (sauf dans les for bien entendu). Il ne peut donc y avoir qu'une seule instruction par ligne.
  5. La dernière instruction avant un tag de fermeture php ("?>") est tout de même suivie d'un point-virgule.
  6. Attachement des parenthèses ouvrantes / instruction de bloc conditionnel ou nom de fonction:
    • if(...)
    • while(...)
    • function MaFonction(...)
    • MaFonction(...);
  7. Détachement des accolades:
    • do {
      • echo $i++;
    • } while($i < 10);
    • if($i > 10) {
      • echo 'Désolé d'avoir affiché "$i" alors que c'était supérieur ou égal à 10...'
    • } elseif($i < 10) {
      • echo 'Apparemment php ne fonctionne pas bien car "$i" est inférieur à 10';
    • } else {
      • echo 'Tout s'est passé comme voulu, c\'est chouette non ?';
    • }
  8. Détachement des opérateurs / opérandes ou parenthèses
    • Valable aussi lors de la concaténation (recollage) de deux chaines, le point doit être prévédé et suivi d'un seul espace: $a . $b
  9. Attachement des opérandes / parenthèses (j'avoue que je ne respecte pas parfaitement cette règle...):
    • $a += 56 + 4 * ($i / 5);
  10. Utiliser dès que c'est possible les opérateurs combinés pour l'assignement: .=, +=, -=, *=, /=, %=, &= etc. (voir et notemment un des commentaires en bas de page)
  11. Les blocs doivent être indentés, et ce avec des tabulations. Dans le cas d'un switch, tout doit être indenté:
    • switch($maVar) {
      • case 'show':
        • echo $monTexte;
        • break;
      • case 'none':
        • break;
      • default:
        • echo 'Une erreur s'est produite, veuillez recommencer';
    • }
  12. Les blocs doivent être ouverts sur la même ligne. Inutile de mettre une nouvelle ligne avec juste pour une accolade ou une parenthèse ouvrante...
    • if($a) {
      • echo $b;
    • }
  13. Utilisation des short-tags "<?" ou "<?=" interdite. Toujours utiliser "<?php" ou "<?php echo ".
  14. Eviter au maximum de mélanger traitement et affichage, et surtout éviter au maximum d'ouvrir et fermer les tags php de multiples fois. Un très bon exemple de ce que je n'aime pas du tout est l'action header de WikiNi...
  15. Il ne peut y avoir d'instruction sur la même ligne qu'une tag php ouvrante ou fermante, mis à part pour une instruction d'affichage en ligne du type
    • <?php echo $a; ?>
  16. Pour l'affichage, utiliser "echo" sans parenthèses et recoller toutes les chaines avant de les passer à "echo" (à moins que ce ne soit moins performant ?), c'est à dire utiliser:
    • echo $a . $b . $c;
  17. plutôt que:
    • echo $a, $b, $c;
  18. qui me parait moins lisible.
    • Oui, c'est moins performant car avec `.', le moteur PHP fait une concaténation inutile, alors qu'avec `,', il ne fait qu'afficher à la suite. Bien sûr cela se compte en centième de seconde. ;) -- MickaelMenu
  19. Les structures conditionnelles peuvent être notées sur une seule ligne, mais elles doivent respecter les points suivants:
    • L'inscrution en elle-même ne doit pas être trop longue (disons maximum 40 à 50 carractères)
    • La règle 1...
    • Il doit y avoir un espace après la parenthèse fermente de la structure conditionnelle.
    • Elle ne peut pas être mélangée avec la synthaxe en bloc, par exemple comme ceci:
      • if($a) { echo $b; } // mauvais
      • if($a) echo $b; // bon
    • L'utilisation d'un for ne contenant aucune instruction est autorisée. Dans ce cas il faut tout de même mettre un espace entre la parenthèse fermante et le point-virgule, pour faire resortir celui-ci:
      • $result = mysql_query('SELECT * FROM matable');
      • for($table = array(); $ligne = mysql_fetch_assoc($result); $table[] = $ligne) ;
  20. Les noms de fonctions, classes et méthodes sont composés de mots dont la première lettre est une majuscule et les autres sont des minuscules. (ceci en fait d'ailleurs des NomWiki...). L'utilisation du chiffre "2" est autorisée pour les fonctions de conversion, marquant ainsi une séparation nette entre l'état en entrée et l'état en sortie. Par exemple nl2br. Elles ne comportent pas d'underscore.
  21. Les noms des variables sont similaires aux noms au noms des fonctions, sauf que le premier mot commence par une minuscule.
-- LordFarquaad
Commentaires [Cacher commentaires/formulaire]