User Tools

Site Tools


backend:phppoo

PHP POO

logo

Site référence

Programmation Orientée Objet

Présentation

La POO (programmation orientée objet) est une forme particulière de programmation destinée à faciliter la maintenance et la réutilisation / adaptation de vos scripts PHP. Elle consiste à représenter des objets (du monde réel ou non) sous une forme d'entités informatiques. On représente généralement un objet global par ce que l'on appelle une classe. Une classe va regrouper un ensemble de fonctions et de propriétés pouvant agir sur l'objet. Si on prend par exemple une voiture dans le monde réel, on peut modéliser une voiture par une classe “Voiture” qui aura comme propriétés le nombre de roues, le nombre de portes, etc …

Définition du vocabulaire

Nom Définition
classe Définition d'un objet
objet Instance d'une classe
propriété Variable d'un objet
méthode Fonction s'appliquant à un objet

Visibilité

La visibilité d'une propriété, d'une méthode ou (à partir de PHP 7.1.0) une constante peut être définie en préfixant sa déclaration avec un mot-clé
- public : Les éléments sont accessibles partout.
- protected : L'accès aux éléments est limité à la classe elle-même, ainsi qu'aux classes qui en héritent et parente.
- private : L'accès aux éléments est uniquement réservé à la classe qui les a définis.

Le constructeur __construct sera toujours public :

__construct ([ mixed $args = "" [, $... ]] ) : void

➔ PHP permet aux développeurs de déclarer des constructeurs pour les classes. Les classes qui possèdent une méthode constructeur appellent cette méthode à chaque création d'une nouvelle instance de l'objet, ce qui est intéressant pour toutes les initialisations dont l'objet a besoin avant d'être utilisé.

PHPdoc

Présentation

PHPDoc est une transposition de Javadoc au langage PHP. Il s'agit d'un standard formalisé pour commenter le code PHP. Il permet d'utiliser des outils tels que phpDocumentor ou Doxygen pour générer la documentation du code, notamment les méthodes publiques, les API, etc. Il permet aussi à certains IDE (Zend Studio (en), NetBeans, etc.) de connaître le type des variables et de lever d'autres ambiguïtés dues au typage faible, améliorant ainsi la complétion de code, le typage objet et le débogage.

Toutes les annotations PHPDoc sont contenues dans DocBlocks et sont illustrées par une ligne multiple avec deux astérisques :

/**
 * @tag ...
 */

Syntaxe

  • @api
  • @author
  • @category
  • @copyright
  • @deprecated
  • @example
  • @filesource
  • @global
  • @ignore
  • @internal
  • @license
  • @link
  • @method
  • @package
  • @param
  • @property
  • @property-read
  • @property-write
  • @return
  • @see
  • @since
  • @source
  • @subpackage
  • @throws
  • @todo
  • @uses & @used-by
  • @var
  • @version

Exemple

<?php
 
/**
 * Form
 *
 * Permet de générer un formulaire rapidement et simplement
 */
class Form
{
    /**
     * data
     *
     * @var array Données utilisées par le formulaire
     */
    private $data[];
 
    /**
     * surround
     *
     * @var string Balise utilisé pour entourer les champs
     */
    public $surround = 'p';
 
    /**
     * __construct Construit l'objet
     *
     * @param  mixed $data Données du formulaire
     * @return void
     */
    public function __construct($data = [])
    {
        $this->data = $data;
    }
 
    /**
     * surround Entoure un code HTML de la balise $surround
     *
     * @param  string $html Code HTML à entouré par le texte HTML
     * @return string
     */
    private function surround(string $html): string
    {
        return '<' . $this->surround . '>' . $html . '</' . $this->surround . '>';
    }
 
    /**
     * getValue
     *
     * @param  string  $index Index de la valeur à récupérer
     * @return string
     */
    private function getValue(string $index): ?string
    {
 
        return isset($this->data[$index]) ? $this->data[$index] : null;
    }
 
    /**
     * input
     *
     * @param  string $name
     * @return string
     */
    public function input(string $name): string
    {
        return $this->surround('<input type="text" name="' . $name . '" value="' . $this->getValue($name) . '">');
    }
 
    /**
     * submit
     *
     * @return string
     */
    public function submit(): string
    {
        return $this->surround('<button type="submit">Envoyer</button>');
    }
}

Classes

Présentation

Une classe regroupe des fonctions et des variables (appelées cette fois “attributs”, car il s'agit des attributs d'une classe) qui interagissent avec l'objet. C'est à dire que pour un objet “voiture” par exemple, vous aurez une classe nommée “Voiture” et vous pourrez avoir une fonction qui modifie le niveau de carburant (le niveau de carburant étant un attribut de la classe que l'on ne peut modifier que via une fonction (appelée “méthode”) qui ira modifier cet attribut). On appelle ce principe l'encapsulation des données, le but de l'encapsulation des données étant de ne pas pouvoir accéder aux données de l'objet directement mais via des fonctions (appelées ici “méthodes”). Chaque attribut peut donc disposer de droits d'accès à l'extérieur de la classe. Nous verrons tout ceci au fur et à mesure que vous lisez cette page.

Création

On utilise class pour déclarer une classe et on met les { } à la ligne :

Par convention, on crée un fichier PHP par classe et on le nomme comme celle-ci et le nom la classe commence par une lettre majuscule.

class Ma_classe
{
	...
}
$maclass = new Ma_classe ();

C'est ce qu'on appelle une instanciation, $maclass est une nouvelle instance de Ma_class, elle va contenir un objet qui est une instance de la classe Ma_class.

Déclaration des propriétés

Les variables au sein d'une classe sont appelées “propriétés”. On peut également les retrouver sous les dénominations “attributs”, “membres” ou “champs”, mais nous conservons l'appellation “propriété” pour cette documentation. Elles sont définies en utilisant un des mots-clés public, protected, ou private, suivi optionellement d'une déclaration de type, suivi d'une déclaration classique de variable. Cette déclaration peut comprendre une initialisation, mais celle-ci doit être une valeur constante, c'est à dire qu'elle doit pouvoir être évaluée pendant la compilation du code, et qu'elle ne peut pas dépendre d'informations déterminées lors de l'exécution de celui-ci pour pouvoir être évaluée.

public/private propriete = valeur

Déclaration des méthodes

On les déclares comme des fonctions.
Pour les appeler, on utilisera $this pour faire référence à l'objet

$this->methode()

On utilise le constructeur __construct pour déclarer une méthode, on peut lui passer des paramètres.

public/private function __construct()

Static

Ce sont des méthodes et propriétés disponible au niveau d'un objet qui n'a pas besoin d'une instance pour fonctionner, on n'est pas obligé de l'instancier.
On ajoute static dans la déclaration

public/private static propriete = valeur
public/private static function ma_fonction()

On n'utilise plus $this→ mais self:: pour faire référence à la classe.

On n'utilise static:: pour faire référence à la classe qui appelle la classe static.

De même pour le nom de la classe :

__CLASS__ est une constante qui donne le nom de la classe en cours.

get_called_class() Retourne le nom de la classe depuis laquelle une méthode statique a été appelée, tel que le Late State Binding (résolution statique à la volée) le détermine.

Héritage

Une classe peut avoir les mêmes propriétés et les mêmes méthodes qu'une propriété dont elle hérite. Il faut appeler la classe parente avec require_once et mettre extends ClasseParente.

On peut alors ajouter et redéfinir certaines propriété ou méthodes. On peut même appeler la méthode parente en faisant

parent::a_methode_parente

Constantes pour les classes

On les déclare en les mettant en majuscule et en utilisant

const CONSTANTE = valeur;

On les appelle en utilisant self::

self::CONSTANTE

Les namespaces

Les namespaces (ou les noms d'espaces) permettent de mieux organiser les classes, un namespace correspond à un répertoire et chaque classe de ce namespace sera un fichier dans ce répertoire.

Les namespaces ne sont pas sensibles à la casse.

Déclaration

On doit le déclarer en début de fichier

namespace MonNamespace

Pour pouvoir appeler un objet de base de PHP (du namespace global), il faut mettre \ devant.

Utilisation

Lorsqu'on doit utiliser une classe d'un namespace, il faut l'indiquer en début de fichier :

use MonNamespace\MaClasse

Alias

On peut associer un alias à un namespace, cela sera intéressant lorsqu'on aura des sous-namespaces imbriqués :

use MonNamespace1\MonNamespace2\MonNamespace3\MaClasse as Mon3

Constante __NAMESPACE__

C'est une constante magique qui est une chaîne de caratères qui contient le nom du namespace courant. Dans l'espace global, sans nom, elle contient une chaîne vide.

Getter et Setter

Il existe le principe “d'encapsulation des données” dont le but est de ne pas pouvoir accéder aux données de l'objet directement, mais via des méthodes appelées “getters” et “setters”.

  • getters pour écupérer la valeur des attributs à l'extérieur d'une classe
  • setters pour modifier la valeur des attributs à partir de l'extérieur de la classe.

Structure simple d'un site

Voici un exemple de structure simple de répertoires et fichiers pour un site :

  • \app (pour mettre les classes du namespace 'app')
  • \pages
    • \templates
      • default.php
    • home.php
    • contact.php
  • \public
    • \css
    • \js
    • index.php

Design Pattern

Un design pattern consiste en un schéma qui forme une solution à un problème connu et fréquent. Il est constitué par un ensemble d'objets décrits par des classes et des relations liant les objets.

Les patterns répondent à des problèmes de conception de logiciels dans le cadre de la programmation par objets. Ce sont des solutions connues et éprouvées dont la conception provient de l'expérience de développeurs. Il n'y a pas d'aspect théorique dans les patterns, notamment pas de formalisation

Singleton

Un objet est un singleton si l'application ne peut contenir qu'un seul objet de ce type à un instant donné.

Certaines ressources d'application sont exclusives, dans le sens où il y a une et une seule ressource de ce type. Par exemple, la connexion à une base par son handle est exclusive. Vous avez besoin de partager le handle dans une application, car ouvrir et fermer continuellement des connexions est une perte de ressources, en particulier lors du traitement d'une seule page. D'autres exemples sont la configuration d'un site internet, la gestion des sessions et la gestion des cookies.

Il faut créer une classe classique (pas static) dont le constructeur ne sera pas public et utliser une autre méthode pour créer une instance :

<?php
class MonSingleton
{
  protected static $instance; // Contiendra l'instance de la classe.
 
  protected function __construct() { } // Constructeur en privé.
 
  public static function getInstance()
  {
    if (!isset(self::$instance)) // Si on n'a pas encore instancié notre classe.
    {
      self::$instance = new self; // On l'instancie
    }
 
    return self::$instance;
  }
}

On peut alors récupérer toujours la même instance.

Factory

Le principe est d'avoir une classe qui va se charger de créer les objets dont on a besoin. Cette classe aura pour rôle de charger les classes qu'on lui passe en argument. On ne placera plus de new dans la partie globale du script afin d'instancier une classe, c'est la factory qui le fera. Voici un exemple simple :

<?php
class ArticleTable(){...}
class VoitureTable(){...}
class UtilisateurTable(){...}
 
class TableFactory()
{
    public static function create($table){
        $class_name = ucfirst($table) . 'Table'; 
        return new $class_name(); 
    }
 
}
// On l'appellera comme ceci :
TableFactory::create('Article'); 

Un autre exemple :

<?php
class DBFactory
{
  public static function load($sgbdr)
  {
    $classe = 'SGBDR_' . $sgbdr;
 
    if (file_exists($chemin = $classe . '.class.php'))
    {
      require $chemin;
      return new $classe;
    }
    else
    {
      throw new RuntimeException('La classe <strong>' . $classe . '</strong> n\'a pu être trouvée !');
    }
  }
}
// On l'appellera comme ceci :
<?php
try
{
  $mysql = DBFactory::load('MySQL');
}
catch (RuntimeException $e)
{
  echo $e->getMessage();
}

Injection de dépendance

L'injection de dépendance (DI) permet de solutionner la problématique de communication entre les classes. C'est un terme sophistiqué pour “faire passer des choses” . Tout ce que cela signifie vraiment, c'est de passer les dépendances d'un objet via le constructeur et / ou les paramètres au lieu de les créer lors de la création de l'objet dans l'objet. L'injection de dépendance peut également se référer aux conteneurs d'injection de dépendance qui automatisent la construction et l'injection.

Strategy

Observer

composer

logo composer

Présentation

Composer est un logiciel gestionnaire de dépendances libre écrit en PHP. Il permet à ses utilisateurs de déclarer et d'installer les bibliothèques dont le projet principal a besoin. Le développement a débuté en avril 2011 et a donné lieu à une première version sortie le 1er mars 2012. Développé au début par Nils Adermann et Jordi Boggiano (qui continuent encore aujourd'hui à le maintenir), le projet est maintenant disponible sur la plateforme GitHub. Il est ainsi développé par toute une communauté.

Installation

Avec cURL

$ curl -sS https://getcomposer.org/installer | php

Avec PHP

$ php -r "readfile('https://getcomposer.org/installer');" | php

Commandes

Composer dispose de plusieurs paramètres dont :

  • require: ajoute la bibliothèque en paramètre au fichier composer.json et l'installe.
  • install : installe toutes les bibliothèques du composer.json. Il s'agit de la commande à lancer pour installer les dépendances d'un dépôt PHP.
  • update : met à jour les bibliothèques du composer.json, selon les versions permises qui y sont mentionnées.
  • remove : désinstalle une bibliothèque et la retire du composer.json.

Symboles des versions

Les symboles permettant d'autoriser plusieurs versions des dépendances sont les suivants:

Symbole Rôle (placé avant un numéro de version) Exemple
>= permet d'en étendre le numéro. De même on trouve les symboles >, <, ⇐. “php”: “>=5.5.9 inclut PHP 7.
!= exclut une version.
- définit une plage de versions.
¦¦ ajoute des versions possibles. “symfony/symfony”: “2.8 ¦¦ 3.0 regroupe uniquement ces deux versions.
* étend à toutes les sous-versions. “symfony/symfony”: “3.1.* comprend la 3.1.1.
~ étend aux versions suivantes du même niveau. “doctrine/orm”: ”~2.5 concerne aussi la 2.6 mais pas la 2.4 ni la 3.0.
^ fait la même chose que tilde sous réserve qu'il y ait une compatibilité ascendante

packagist

logo packagist

Présentation

Packagist est le référentiel principal de Composer. Il regroupe les packages PHP publics installables avec Composer.

Packages utiles

Faker

Faker est une bibliothèque PHP qui génère de fausses données.

Installation
composer require fzaninotto/faker --dev
Utilisation

On crée une variable contenant l'objet Faker :

$faker = Faker\Factory::create('fr_FR');

On appelle un des méthodes de l'objet :

$category->setTitle($faker->sentence())
$user->setFirstName($faker->firstname())
$pin->setDescription($faker->text($maxNbChars = 200))
Vidéos

Lior Chamla : Il en parle dans la vidéo 🎵 SYMFONY 3/4 - 1H POUR COMPRENDRE LES ENTITES ET LEURS RELATIONS ! : Passage correspondant

Voici d'autres packages utiles

backend/phppoo.txt · Last modified: 2020/09/19 01:15 (external edit)