Normes de codes
Les développeurs de CakePHP vont utiliser le guide pour l’écriture de code
PSR-12 en plus des règles de code
suivantes.
Il est recommandé que les autres personnes qui développent des Ingrédients de
Cake suivent les mêmes normes.
Vous pouvez utiliser le Code Sniffer de CakePHP pour vérifier que votre code
suit les normes requises.
Ajout de Nouvelles Fonctionnalités
Aucune nouvelle fonctionnalité ne devrait être ajoutée, sans avoir fait ses
propres tests - qui doivent être validés avant de les committer au dépôt.
Configuration de l’IDE
Merci de vous assurer que votre IDE est configuré avec « trim right » pour les
espaces vides. Il ne doit pas y a voir d’espaces à la fin des lignes.
La plupart des IDE modernes supporte aussi un fichier .editorconfig
. Le
squelette d’application CakePHP est fourni avec par défaut. Il contient déjà
les meilleurs pratiques par défaut.
Indentation
Quatre espaces seront utilisés pour l’indentation.
Ainsi, l’indentation devrait ressembler à ceci:
// niveau de base
// niveau 1
// niveau 2
// niveau 1
// niveau de base
Ou:
$booleanVariable = true;
$stringVariable = "moose";
if ($booleanVariable) {
echo "Valeur booléenne si true";
if ($stringVariable === "élan") {
echo "Nous avons rencontré un élan";
}
}
Dans les cas où vous utilisez un appel de fonction multi-lignes, utilisez les
instructions suivantes:
Les parenthèses ouvrantes d’un appel de fonction multi-lignes doivent être
le dernier contenu de la ligne.
Seul un argument est permis par ligne dans un appel de fonction multi-lignes.
Les parenthèses fermantes d’un appel de fonction multi-lignes doivent être
elles-même sur une ligne.
Par exemple, plutôt qu’utiliser le format suivant:
$matches = array_intersect_key($this->_listeners,
array_flip(preg_grep($matchPattern,
array_keys($this->_listeners), 0)));
Utilisez ceci à la place:
$matches = array_intersect_key(
$this->_listeners,
array_flip(
preg_grep($matchPattern, array_keys($this->_listeners), 0)
)
);
Longueur des lignes
Il est recommandé de garder les lignes à une longueur d’environ 100 caractères
pour une meilleure lisibilité du code.
Les lignes ne doivent pas être plus longues que 120 caractères.
En résumé:
Structures de Contrôle
Les structures de contrôle sont par exemple « if
», « for
», « foreach
»,
« while
», « switch
» etc. Ci-dessous, un exemple avec « if
»:
if ((expr_1) || (expr_2)) {
// action_1;
} elseif (!(expr_3) && (expr_4)) {
// action_2;
} else {
// default_action;
}
Dans les structures de contrôle, il devrait y avoir 1 (un) espace avant la
première parenthèse et 1 (un) espace entre les dernières parenthèses et
l’accolade ouvrante.
Toujours utiliser des accolades dans les structures de contrôle,
même si elles ne sont pas nécessaires. Elles augmentent la lisibilité
du code, et elles vous donnent moins d’erreurs logiques.
L’ouverture des accolades doit être placée sur la même ligne que la
structure de contrôle. La fermeture des accolades doit être placée sur de
nouvelles lignes, et ils doivent avoir le même niveau d’indentation que
la structure de contrôle. La déclaration incluse dans les accolades doit
commencer sur une nouvelle ligne, et le code qu’il contient doit gagner un
nouveau niveau d’indentation.
Les attributs inline ne devraient pas être utilisés à l’intérieur des
structures de contrôle.
// mauvais = pas d'accolades, déclaration mal placée
if (expr) statement;
// mauvais = pas d'accolades
if (expr)
statement;
// bon
if (expr) {
statement;
}
// mauvais = inline assignment
if ($variable = Class::function()) {
statement;
}
// bon
$variable = Class::function();
if ($variable) {
statement;
}
Opérateurs Ternaires
Les opérateurs ternaires sont permis quand l’opération entière rentre sur une
ligne. Les opérateurs ternaires plus longs doivent être séparés en
expression if else
. Les opérateurs ternaires ne doivent pas être imbriqués.
Des parenthèses optionnelles peuvent être utilisées autour de la condition
vérifiée de l’opération pour rendre le code plus clair:
// Bien, simple et lisible
$variable = isset($options['variable']) ? $options['variable'] : true;
// Imbrications des ternaires est mauvaise
$variable = isset($options['variable']) ? isset($options['othervar']) ? true : false : false;
Fichiers de Template
Dans les fichiers de template (fichiers .php) les développeurs devront utiliser
les structures de contrôle en mot (keyword control structures).
Les structures de contrôle en mot sont plus faciles à lire dans des fichiers
de template complexes. Les structures de contrôle peuvent soit être contenues
dans un block PHP plus large, soit dans des balises PHP séparées:
<?php
if ($isAdmin):
echo '<p>Vous êtes l utilisateur admin.</p>';
endif;
?>
<p>Ce qui suit suit est aussi acceptable:</p>
<?php if ($isAdmin): ?>
<p>Vous êtes l utilisateur admin.</p>
<?php endif; ?>
Comparaison
Toujours essayer d’être aussi strict que possible. Si un test non strict est
délibéré, il peut être sage de le commenter afin d’éviter de le confondre avec
une erreur.
Pour tester si une variable est null, il est recommandé d’utiliser une
vérification stricte:
if ($value === null) {
// ...
}
La valeur avec laquelle on vérifie devra être placée sur le côté droit:
// non recommandé
if (null === $this->foo()) {
// ...
}
// recommandé
if ($this->foo() === null) {
// ...
}
Appels des Fonctions
Les fonctions doivent être appelées sans espace entre le nom de la fonction et
la parenthèse ouvrante. Il doit y avoir un espace entre chaque paramètre d’un
appel de fonction:
$var = foo($bar, $bar2, $bar3);
Comme vous pouvez le voir, il doit y avoir un espace des deux côtés des signes
égal (=).
Définition des Méthodes
Exemple d’une définition de méthode:
public function someFunction($arg1, $arg2 = '')
{
if (expr) {
statement;
}
return $var;
}
Les paramètres avec une valeur par défaut, doivent être placés en dernier dans
la définition de la fonction. Essayez de faire en sorte que vos fonctions
retournent quelque chose, au moins true
ou false
, ainsi cela peut
déterminer si l’appel de la fonction est un succès:
public function connection($dns, $persistent = false)
{
if (is_array($dns)) {
$dnsInfo = $dns;
} else {
$dnsInfo = BD::parseDNS($dns);
}
if (!($dnsInfo) || !($dnsInfo['phpType'])) {
return $this->addError();
}
return true;
}
Il y a des espaces des deux côtés du signe égal.
Typehinting
Les arguments qui attendent des objets, des tableaux ou des callbacks
(fonctions de rappel) peuvent être typés. Nous ne typons que les méthodes
publiques car le typage prend du temps:
/**
* Some method description.
*
* @param \Cake\ORM\Table $table The table class to use.
* @param array $array Some array value.
* @param callable $callback Some callback.
* @param bool $boolean Some boolean value.
*/
public function foo(Table $table, array $array, callable $callback, $boolean)
{
}
Ici $table
doit être une instance de \Cake\ORM\Table
, $array
doit
être un array
et $callback
doit être de type callable
(un callback
valide).
Notez que si vous souhaitez autoriser que $array
soit aussi une instance de
\ArrayObject
, vous ne devez pas typer puisque array
accepte seulement le
type primitif:
/**
* Description de la method.
*
* @param array|\ArrayObject $array Some array value.
*/
public function foo($array)
{
}
Fonctions Anonymes (Closures)
La définition des fonctions anonymes suit le guide sur le style de codage
PSR-12, où elles sont déclarées
avec un espace après le mot clé function, et un espace avant et après
le mot clé use:
$closure = function ($arg1, $arg2) use ($var1, $var2) {
// code
};
Chaînage des Méthodes
Le chaînage des méthodes doit avoir plusieurs méthodes réparties sur des
lignes distinctes et indentées avec quatre espaces:
Inclure les Fichiers
include
, require
, include_once
et require_once
n’ont pas de
parenthèses:
// mauvais = parenthèses
require_once('ClassFileName.php');
require_once ($class);
// bon = pas de parenthèses
require_once 'ClassFileName.php';
require_once $class;
Quand vous incluez les fichiers avec des classes ou librairies, utilisez
seulement et toujours la fonction
require_once.
Les Balises PHP
Toujours utiliser les balises longues (<?php ?>
) plutôt que les balises
courtes (<? ?>
). L’echo court doit être utilisé dans les fichiers de
template (.php) lorsque cela est nécessaire.
Echo court
L’echo court doit être utilisé dans les fichiers de vue à la place de
<?php echo
. Il doit être immédiatement suivi par un espace unique, la
variable ou la valeur de la fonction pour faire un echo
, un espace unique,
et la balise de fermeture de php:
// wrong = semicolon, aucun espace
<td><?=$name;?></td>
// good = espaces, aucun semicolon
<td><?= $name ?></td>
Depuis PHP 5.4, le tag echo court (<?=
) ne doit plus être considéré.
un “tag court” est toujours disponible quelque soit la directive ini de
short_open_tag
.
Convention de Nommage
Fonctions
Ecrivez toutes les fonctions en camelBack:
function nomDeFonctionLongue()
{
}
Classes
Les noms de classe doivent être écrits en CamelCase, par exemple:
Variables
Les noms de variable doivent être aussi descriptifs que possible, mais aussi
courts que possible. Tous les noms de variables doivent démarrer avec une lettre
minuscule, et doivent être écrites en camelBack s’il y a plusieurs mots. Les
variables contenant des objets doivent d’une certaine manière être associées à
la classe d’où elles proviennent. Exemple:
$user = 'John';
$users = ['John', 'Hans', 'Arne'];
$dispatcher = new Dispatcher();
Visibilité des Membres
Utilisez les mots clés public
, protected
et private
de PHP pour les
méthodes et les variables.
Exemple d’Adresses
Pour tous les exemples d’URL et d’adresse email, utilisez « example.com »,
« example.org » et « example.net », par exemple:
Le nom de domaine « example.com » est réservé à cela (voir RFC 2606) et est
recommandé pour l’utilisation dans la documentation ou comme exemples.
Fichiers
Les noms de fichier qui ne contiennent pas de classes, doivent être écrits en
minuscules et soulignés, par exemple:
Casting
Pour le casting, nous utilisons:
- Type
Description
- (bool)
Cast pour boolean.
- (int)
Cast pour integer.
- (float)
Cast pour float.
- (string)
Cast pour string.
- (array)
Cast pour array.
- (object)
Cast pour object.
Constantes
Les constantes doivent être définies en majuscules:
Si un nom de constante a plusieurs mots, ils doivent être séparés par un
caractère underscore, par exemple:
define('NOM_LONG_DE_CONSTANTE', 2);
Attention quand vous utilisez empty()/isset()
While empty()
often seems correct to use, it can mask errors
and cause unintended effects when '0'
and 0
are given. When variables or
are already defined, the usage of empty()
is not recommended. When working
with variables, it is better to rely on type-coercion to boolean instead of
empty()
:
function manipulate($var)
{
// Not recommended, $var is already defined in the scope
if (empty($var)) {
// ...
}
// Use boolean type coercion
if (!$var) {
// ...
}
if ($var) {
// ...
}
}
When dealing with defined properties you should favour null
checks over
empty()
/isset()
checks:
class Thing
{
private $property; // Defined
public function readProperty()
{
// Not recommended as the property is defined in the class
if (!isset($this->property)) {
// ...
}
// Recommended
if ($this->property === null) {
}
}
}
When working with arrays, it is better to merge in defaults over using
empty()
checks. By merging in defaults, you can ensure that required keys
are defined:
function doWork(array $array)
{
// Merge defaults to remove need for empty checks.
$array += [
'key' => null,
];
// Not recommended, the key is already set
if (isset($array['key'])) {
// ...
}
// Recommended
if ($array['key'] !== null) {
// ...
}
}