Programmation
Le passage en programmation PHP orientée objet est toujours en cours.
Je vais essayer ici de condenser les cours en règles simple, une sorte d’aide mémoire.
- La programmation orientée objet
- La convention de codage PEAR
- Les principes SOLID
- Le paradigme MVC
- La modélisation UML
/! – En cours de rédaction - /!
La programmation orientée objet
CF : http://fr.openclassrooms.com/informatique/cours/programmez-en-oriente-objet-en-php – http://jcrozier.developpez.com/tutoriels/web/php/programmation-orientee-objet/ – http://alain-sahli.developpez.com/tutoriels/php/les-interfaces/ – http://stephaneey.developpez.com/tutoriel/php/php5_nouveautes/ – Livre PHP 5 avancé
::
Les classes
Une classe contient des attributs (variables) et des méthodes (fonctions). Les classes servent de modèle pour les objets.
class MaClasse { ... }
Convention de nommage PEAR : Les déclaration de classes ouvrent l’accolade sur une nouvelle ligne. Les classes doivent avoir un nom parlant. éviter les abréviations lorsque cela est possible. Les noms de classes doivent toujours commencer par une majuscule. L’architecture hiérarchique des classes PEAR se retrouve aussi dans le nom de la classe, chaque niveau de la hiérarchie étant séparé par un unique trait souligné ‘_’.
::
Les méthodes
Dans une classe, une méthode est une fonction. Une méthode peut être :
- publique : visible en dehors de la classe.
- protégé : visible dans les classes enfants.
- privé : visible unique de la classe.
- statique (en plus) : commune à la classe, et donc partagée par toutes les instances.
- finale (en plus) : ne peut pas être remplacée dans une classe enfant.
Les méthodes devraient être par défaut publiques ou protégées pour être utilisables par les classes enfants.
class MaClasse { public function $ajouterNombre() { ... } protected function $soustraireNombre() { ... } private function $_supprimerNombre() { ... } public static function $ajouterStaticNombre() { ... } protected static function $soustraireStaticNombre() { ... } private static function $_supprimerStaticNombre() { ... } public final function $ajouterFinalNombre() { ... } protected final function $soustraireFinalNombre() { ... } private final function $_supprimerFinalNombre() { ... } }
Il existe des méthodes dites magiques. Celles-ci ont des noms prédéfinis commençant par un double souligné ‘__
‘ et sont utilisées par défaut si présentes lors de certaines opérations.
Convention de nommage PEAR : 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. Les méthodes doivent être nommées en utilisant le style « studly caps », c’est à dire l’utilisation de majuscules en milieu de mot pour marquer visuellement la séparation entre les mots sans utiliser d’espaces ou séparateurs. Les méthodes privés d’une classe sont précédés d’un simple souligné ‘_’. Les méthodes protégés d’une classe ne sont pas précédés par un souligné ‘_’.
::
Les attributs
Dans une classe, un attribut est une variable. Un attribut peut être :
- publique : visible en dehors de la classe.
- protégé : visible dans les classes enfants.
- privé : visible unique de la classe.
- statique (en plus) : valeur commune à la classe, et donc valeur partagée par toutes les instances.
Les attributs doivent être par défaut privés ou protégés pour être utilisables par les classes enfants.
class MaClasse { public $variablePublic; protected $variableProtegee; private $_variablePrivee; public static $variableStaticPublic; protected static $variableStaticProtegee; private static $_variableStaticPrivee; const AXIOM_AJOUTER = 1; }
On ne doit pas utiliser d’attributs publiques. On accède aux attributs via des méthodes afin de pouvoir mieux contrôler leur consultation et modification.
Convention de nommage PEAR : Les attributs doivent être nommées en utilisant le style « studly caps », c’est à dire l’utilisation de majuscules en milieu de mot pour marquer visuellement la séparation entre les mots sans utiliser d’espaces ou séparateurs. Les attributs privés d’une classe sont précédés d’un simple souligné ‘_’. Les attributs protégés d’une classe ne sont pas précédés par un souligné ‘_’. Les constantes doivent toujours être en majuscule, les mots séparés par des ‘_’. Préfixez les noms des constantes avec le nom en majuscule de la classe/paquetage dans laquelle elles sont utilisées.
::
Les objets (instances)
Créer une instance à partir d’une classe, l’instanciation d’une classe, c’est créer un objet. Cet objet contient par héritage tous les attributs et méthodes de la classe utilisée et des classes parents. Cet objet est autonome, ses attributs ont des valeurs spécifique à cet objet. Un autre objet aura les mêmes attributs mais avec des valeurs différentes.
classe MaClass { ... } $objet = new MaClasse();
Lors de la création de l’objet, si la méthode magique __construct
est présente, elle est appelée.
On peut vérifier qu’une variable est bien un objet instancié d’un certaine classe :
if ($objet instanceof MaClass) { ... }
Pour supprimer proprement un objet, on utiliser unset($objet)
qui utilise la méthode magique __destruct
si présente.
::
Utiliser les méthodes dans les objets
Dans un objet, les méthodes non statiques sont accessibles via $this->methode($parametres)
. $this
est un mot clé qui désigne l’objet en cours. methode
désigne la méthode que l’on souhaite utiliser. $parametres
désigne le ou les paramètres que l’on veut transmettre à la méthode.
En dehors de l’objet, les méthodes publiques (public
) sont accessible via $objet->methode($parametres)
. $objet
désigne l’objet sur lequel on souhaite appliquer la méthode.
Les méthodes privées (private
) ne sont pas accessibles en dehors de l’objet.
::
Utiliser les méthodes dans les classes
Une méthode statique (static
) appartient à une classe et non aux instances de cette classe.
Dans une classe, les méthodes statiques (static
) sont accessibles via self::methode($parametres)
. self
est un mot clé qui désigne la classe utilisée.
En dehors de la classe, les méthodes publiques (public
) et statiques (static
) sont accessibles via classe::methode($parametres)
. classe
désigne la classe utilisée.
Les méthodes privées (private
) ne sont pas accessibles en dehors de l’objet.
::
Utiliser les attributs dans les objets
Dans un objet, les attributs non statiques sont accessibles via $this->attribut
. $this
est un mot clé qui désigne l’objet en cours. attribut
désigne l’attribut que l’on souhaite utiliser.
En dehors de l’objet, les attributs publics (public
) sont accessible via $objet->attribut
. $objet
désigne l’objet sur lequel on souhaite appliquer la méthode.
Les attributs privés (private
) ne sont pas accessibles en dehors de l’objet.
::
Utiliser les attributs dans les classes
Un attribut statique (static
) appartient à une classe et non aux instances de cette classe. Tous les objets instanciés de la classe utilisent le même attribut avec son contenu commun.
Dans une classe, les attributs statiques (static
) sont accessibles via self::$attribut
. self
est un mot clé qui désigne la classe utilisée. $attribut
désigne l’attribut que l’on souhaite utiliser.
En dehors de la classe, les attributs publics (public
) et statiques (static
) sont accessibles via classe::$attribut
. classe
désigne la classe utilisée.
Les attributs privés (private
) ne sont pas accessibles en dehors de l’objet.
::
Utiliser les variables hors des objets
Dans un objet, une méthode fonctionne comme une fonction. Si on a besoin d’utiliser une variable défini hors des classes et objets, il faut l’appeler comme on l’appellerais depuis une fonction classique, c’est à dire :
class MaClasse { public function maFonction() { global $maVariableGlobale; echo $maVariableGlobale; } }
::
Utiliser les constantes
Une constante appartient à une classe et non aux instances de cette classe. Un constante est forcément publique et non modifiable.
Dans une instance de la classe, les constantes sont accessibles via self::CONSTANTE
. self
désigne la classe utilisée. CONSTANTE
désigne la constante que l’on souhaite utiliser.
En dehors de l’instance de la classe, les constantes sont accessibles via classe::methode($parametres)
. classe
désigne la classe utilisée. CONSTANTE
désigne la constante que l’on souhaite utiliser.
::
Les classes enfants et l’héritage
Une classe enfant hérite automatiquement de tous les attributs et méthodes de la classe parent. De nouveaux attributs et méthodes peuvent être ajoutés.
Un attribut avec une valeur par défaut peut être remplacé pour avoir une nouvelle valeur, mais le type d’attribut doit être le même.
Une méthode peut être remplacée par une nouvelle si la méthode de la classe parente n’est pas marquée comme finale (final). Une méthode remplacée doit de plus avoir les même arguments, tout au plus peut-on ajouter des arguments optionnels, cà d avec une valeur par défaut.
class MaClasse { ... } class MaClasseEnfant extends MaClasse { ... }
On peut appeler une méthode de la classe parente plutôt que la même méthode redéfinie par la classe fille avec parent::methode()
, cependant c’est un grand risque de confusion, à éviter donc.
::
Les classes abstraites
Une classe abstraite est une classe qui ne peut pas être utilisée directement pour faire des objets. Mais elle permet de définir certains attributs et méthodes par défaut pour des classes enfants.
abstract class MaClasse { ... } class MaClasseEnfant extends MaClasse { ... }
::
Les interfaces
L’interface est un contrat de service minimum. Une classe qui prétend utiliser une interface est tenu d’implémenter tous les méthodes publiques définis dans l’interface. C’est une bonne pratique de programmation pour les gros projets avec de multiples intervenants et beaucoup de classes similaires.
interface interfaceDeClasse { public $variablePublic; public function $ajouterNombre(); } class MaClasse implements interfaceDeClasse { public $variablePublic; public function $ajouterNombre() { ... } }
Une classe peut dépendre de plusieurs interfaces. Les interfaces sont séparées par une virgule : class MaClasse implements interfaceDeClasse1, interfaceDeClasse2
Une ou plusieurs interfaces peuvent étendre une interface. Les interfaces sont séparées par une virgule : interface interfaceDeClasse extends interfaceDeClasse1, interfaceDeClasse2
::
Les getter et setter
A faire…
::
Les constructeurs et dé-constructeurs
A faire…
::
Copie et clonage d’objets
Par défaut en PHP5, un objet est toujours transmis par référence. Copier un objet dans une nouvelle variable n’est fait pas un nouvelle objet, on utiliser toujours le même objet.
$objet2 = $objet;
Pour en faire une vraie copie autonome, il faut explicitement demander à en faire un clone :
$objet3 = clone $objet;
Il est possible de définir la méthode magique __clone
pour forcer certaines opérations lorsque l’on clone un objet. Par exemple, si chaque objet doit avoir un ID unique.
Pour tester si deux objets sont égaux dans leur contenus, on utilise le double égal ‘==
‘ :
if ($objet2 == $objet1) { ... }
Pour tester si deux variables contiennent le même objet, et pas juste leur contenu, on utiliser le triple égal ‘===
‘ :
if ($objet2 === $objet1) { ... }
La convention de codage PEAR
CF : http://pear.php.net/manual/fr/standards.php
- Indentation et longueur de lignes. Utilisez une indentation des 4 espaces, sans tabulation.
- Structures de Contrôles. Les instructions de contrôle doivent avoir un espace entre le mot clé de l’instruction et la parenthèse ouvrante, afin de les distinguer des appels de fonctions. Il est vivement recommandé de toujours utiliser des accolades, même dans les situations où elles sont techniquement optionnelles.
- Appels de Fonctions. 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. Il doit y avoir au moins un espace de chaque côté du signe égal utilisé pour affecter la valeur de retour de la fonction à une variable.
- Définitions des classes. Les déclaration de classes ouvrent l’accolade sur une nouvelle ligne.
- Définitions des fonctions. 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.
- Commentaires. Les commentaires du type C (
/* */
) et les commentaires standard C++ (//
) sont tous les deux acceptés. Les commentaires de type Perl/shell (#) sont à éviter. - Inclure du Code. 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), utilisezinclude_once
. Ces deux méthodes s’assurent que le fichier classe n’est inclus qu’une seule fois. - Tags dans le Code PHP. Utilisez toujours
<?php ?>
pour délimiter du code PHP, et non la version abrégée<? ?>
. - Commentaires d’En-tête. Tous les fichiers de code source qui se trouvent dans le dépôt de PEAR doivent contenir le bloc de commentaires d’en-tête : Un bloc de commentaire « page-level » en début de chaque fichier, et un bloc de commentaires « class-level » juste au dessus de chaque classe.
- Utilisation de CVS. Inclure le mot clé CVS
$Id$
dans chaque fichier. - Exemple d’URLs. Utilisez
example.com
,example.org
etexample.net
pour tous les exemples d’URLs et exemples d’email (RFC 2606). - Conventions de Nom. Les classes doivent avoir un nom parlant. éviter les abréviations lorsque cela est possible. Les noms de classes doivent toujours commencer par une majuscule. L’architecture hiérarchique des classes PEAR se retrouve aussi dans le nom de la classe, chaque niveau de la hiérarchie étant séparé par un unique trait souligné ‘_’. Les attributs et les méthodes doivent être nommées en utilisant le style « studly caps« , c’est à dire l’utilisation de majuscules en milieu de mot pour marquer visuellement la séparation entre les mots sans utiliser d’espaces ou séparateurs. Les fonctions doivent de plus avoir le nom du paquetage comme préfixe, pour éviter les doublons entre les paquetages. Les éléments (méthodes, attributs) privés d’une classe sont précédés d’un simple souligné ‘_’. Les membres protégés d’une classe ne sont pas précédés par un souligné ‘_’. Les constantes doivent toujours être en majuscule, les mots séparés par des ‘_’. Préfixez les noms des constantes avec le nom en majuscule de la classe/paquetage dans laquelle elles sont utilisées. Si votre paquetage a besoin de définir des variables globales, leurs noms doivent commencer par un simple ‘_’ suivi par le nom du paquetage et un autre ‘_’.
- Formats des fichiers. Tous les scripts apportés à PEAR doivent être stockés comme du texte ASCII, utiliser le jeux de caractères ISO-8859-1, et être formaté Unix. Il ne doit y avoir qu’un seul retour à la ligne après la fermeture du tag PHP (
?>
). Cela signifie que lorsque le curseur est à la fin du fichier, il doit y avoir une seule après le tag PHP fermant. - E_STRICT-compatible code. Depuis le 1er janvier 2006, tout nouveau code proposé pour PEAR doit être compatible
E_STRICT
. Cela signifie qu’il ne doit pas produire de warning ou d’erreur quand le niveau de rapport d’erreur de php est au niveauE_STRICT
. - Guide de gestion des erreurs. Cette partie définit comment sont prises en compte les erreurs dans les paquetages PEAR programmés en PHP 5 et 6.
- Les bonnes pratiques. Il y a d’autres choses qui ne sont pas couvertes par la convention de codage PEAR qui sont plus sujettes à des préférences personnelles et qui ne sont pas directement liées à la lisibilité du code. Par exemple, l’utilisateur des simples ou des doubles guillemets est permis par PHP lui-même afin de rendre la programmation plus simple et il n’y a aucune raison d’utiliser plutôt l’un que l’autre. Ce choix appartient au développeur. La seule recommandation que nous pouvons faire est de conserver votre choix dans un même paquet et de respecter le style personnel des autres développeurs.
- Fichier exemple. CF http://pear.php.net/manual/fr/standards.sample.php
Le point 10 n’est pas applicable du fait de l’environnement propre à nebule.
Les principes SOLID
CF : http://blog.xebia.fr/2011/07/18/les-principes-solid/ – http://fr.wikipedia.org/wiki/SOLID_%28informatique%29
- Single responsibility principle. Une classe doit avoir une et une seule responsabilité.
- Open close principle. Une classe doit être ouverte à l’extension, mais fermée à la modification.
- Liskov principle. Une classe doit pouvoir être remplacée par une instance d’un de ses sous-types, sans modifier la cohérence du programme.
- Interface segregation principle. Préférer plusieurs interfaces spécifiques pour chaque client plutôt qu’une seule interface générale.
- Dependency inversion principle. Il faut dépendre des abstractions, pas des implémentations.
Le paradigme MVC
CF : http://fr.wikipedia.org/wiki/Mod%C3%A8le-vue-contr%C3%B4leur
A faire…
La modélisation UML
CF : http://fr.wikipedia.org/wiki/UML_%28informatique%29 – http://fr.openclassrooms.com/informatique/cours/debutez-l-analyse-logicielle-avec-uml
A titre personnel, je suis peu enclin à réaliser une analyse préalable. Si le but du programme est clair, alors sa programmation est claire aussi et transpire la logique du programme. Ici, dans le cadre de nebule et sylabe, dans un état expérimental, il est difficile de créer une analyse qui ne sera pas remise en question à la moindre découverte lors de l’évolution des projets…
Mais une modélisation, attachée à une documentation, est sûrement quelque chose d’appréciable pour comprendre à posteriori le fonctionnement de l’ensemble.
A faire…
Une réflexion sur « Programmation »