Normes de codes

Les développeurs de CakePHP vont utiliser les normes de code suivantes.

Il est recommandé que les autres personnes qui développent des IngredientsCake suivent les mêmes normes.

Vous pouvez utiliser le CakePHP Code Sniffer pour vérifier que votre code suit les normes requises.

Langue

Tout code et commentaire doit être écrit en Anglais.

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.

Indentation

Un onglet sera utilisé 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 boléenne si true";
    if ($stringVariable === "moose") {
        echo "Nous avons rencontré un moose";
    }
}

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 meilleur lisibilité du code. Les lignes ne doivent pas être plus longues que 120 caractères.

En résumé:

  • 100 caractères est la limite soft.

  • 120 caractères est la limite hard.

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;

// Imbriquations des ternaires est mauvaise
$variable = isset($options['variable']) ? isset($options['othervar']) ? true : false : false;

Fichiers de Vue

Dans les fichiers de vue (fichiers .ctp) 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 vue complexes. Les structures de contrôle peuvent soit être contenues dans un block PHP plus large, soit dans des balises PHP séparés:

<?php
if ($isAdmin):
    echo '<p>You are the admin user.</p>';
endif;
?>
<p>The following is also acceptable:</p>
<?php if ($isAdmin): ?>
    <p>You are the admin user.</p>
<?php endif; ?>

Nous autorisons les balises PHP fermantes (?>) à la fin des fichiers .ctp.

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’un 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éfintion 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 ou des tableaux peuvent être typés:

/**
 * Some method description.
 *
 * @param Model $Model Le model à utiliser.
 * @param array $array Une valeur de tableau.
 * @param bool $boolean Une valeur boléenne.
 */
public function foo(Model $Model, array $array, $boolean) {
}

Ici $Model doit être une instance de Model et $array doit être un array.

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) {
}

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 une tabulation:

$email->from('[email protected]')
    ->to('[email protected]')
    ->subject('Un super message')
    ->send();

DocBlocks

Tous les blocs de commentaire, à l’exception du premier bloc dans un fichier, doit toujours être précédé d’une ligne vierge.

DocBlock d’Entête de Fichier

Tous les fichier PHP doivent contenir un DocBlock d’en-tête, qui doit ressembler à cela:

<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link          https://cakephp.org CakePHP(tm) Project
* @since         X.Y.Z
* @license       https://www.opensource.org/licenses/mit-license.php MIT License
*/

les tags phpDocumentor à inclure sont:

DocBlocks de Classe

Les DocBlocks de classe doivent ressembler à ceci:

/**
 * Short description of the class.
 *
 * Long description of class.
 * Can use multiple lines.
 *
 * @deprecated 3.0.0 Deprecated in 2.6.0. Will be removed in 3.0.0. Use Bar instead.
 * @see Bar
 * @link https://book.cakephp.org/2.0/en/foo.html
 */
class Foo {

}

Les classes DocBlocks peuvent contenir les tags de phpDocumentor suivants:

DocBlocks des Attributs

Les DocBlocks des attributs doivent ressembler à cela:

/**
 * @var string|null Description of property.
 *
 * @deprecated 3.0.0 Deprecated as of 2.5.0. Will be removed in 3.0.0. Use $_bla instead.
 * @see Bar::$_bla
 * @link https://book.cakephp.org/2.0/en/foo.html#properties
 */
protected $_bar = null;

Les DocBlocks des attributs peuvent contenir les tags phpDocumentor suivants:

DocBlocks des Méthodes/Fonctions

Les DocBlocks de méthode ou de fonctions doivent ressembler à ceci:

/**
 * Short description of the method.
 *
 * Long description of method.
 * Can use multiple lines.
 *
 * @param string $param2 first parameter.
 * @param array|null $param2 Second parameter.
 * @return array An array of cakes.
 * @throws Exception If something goes wrong.
 *
 * @link https://book.cakephp.org/2.0/en/foo.html#bar
 * @deprecated 3.0.0 Deprecated as of 2.5.0. Will be removed in 3.0.0. Use Bar::baz instead.
 * @see Bar::baz
 */
 public function bar($param1, $param2 = null) {
 }

Les DocBlocks des méthodes/fonctions peuvent contenir les tags phpDocumentor suivants:

Types de Variables

Les types de variables pour l’utilisation dans DocBlocks:

Type

Description

mixed

Une variable avec un type indéfini (ou multiple).

int

Variable de type Integer (Tout nombre).

float

Type Float (nombres à virgule).

bool

Type Logique (true ou false).

string

Type String (toutes les valeurs en «  «  ou “ “).

null

Type null. Habituellement utilisé avec un autre type.

array

Type Tableau.

object

Type Objet.

resource

Type Ressource (retourné par exemple par mysql_connect()). Rappelez vous que quand vous spécifiez un type en mixed, vous devez indiquer si il est inconnu, ou les types possibles.

callable

Function appelable.

Vous pouvez aussi combiner les types en utilisant le caractère pipe:

int|bool

Pour plus de deux types, il est habituellement mieux d’utiliser seulement mixed.

Quand vous retournez l’objet lui-même, par ex pour chaîner, vous devriez utilisez $this à la place:

/**
 * Foo function.
 *
 * @return $this
 */
public function foo() {
    return $this;
}

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 Tags PHP

Toujours utiliser les tags longs (<?php ?>) plutôt que les tags courts (<? ?>).

Convention de Nommage

Fonctions

Ecrivez toutes les fonctions en camelBack:

function nomDeFonctionLongue() {
}

Classes

Les noms de classe doivent être écrites en CamelCase, par exemple:

class ClasseExemple {
}

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 si 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 = array('John', 'Hans', 'Arne');

$dispatcher = new Dispatcher();

Visibilité des Membres

Utilisez les mots-clés private et protected de PHP5 pour les méthodes et variables. De plus les noms des méthodes et variables protégées commencent avec un underscore simple (_). Exemple:

class A {
    protected $_jeSuisUneVariableProtegee;

    protected function _jeSuisUnemethodeProtegee() {
       /*...*/
    }
}

Les noms de méthodes et variables privées commencent avec un underscore double (__). Exemple:

class A {
    private $__iAmAPrivateVariable;

    private function __iAmAPrivateMethod() {
        /*...*/
    }
}

Essayez cependant d’éviter les méthodes et variables privées et privilégiez plutôt les variables protégées. Ainsi elles pourront être accessible ou modifié par les sous-classes, alors que celles privées empêchent l’extension ou leur réutilisation. La visibilité privée rend aussi le test beaucoup plus difficile.

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:

nom_de_fichier_long.php

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:

define('CONSTANTE', 1);

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);