Mis à jour le vendredi 29 septembre 2017
  • 30 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Description de l'application

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Il serait temps de faire un TP conséquent pour mettre en pratique tout ce que nous avons vu : nous allons réaliser un site web (souvent comparé à une application). En effet, vous avez maintenant toutes les connaissances nécessaires pour réaliser un tel projet. Ce sera donc l'occasion de faire un point sur vos connaissances en orienté objet. Si vous pensez que vous êtes à l'aise avec l'orienté objet, ce TP sera l'occasion de vérifier cela. Si vous avez toujours du mal, alors ce TP vous aidera de façon très concrète.

Pour y arriver, nous allons créer une bibliothèque (terme que nous allons définir dès ce premier chapitre), un module de news avec commentaires ainsi qu'un espace d'administration complet. Le plus difficile consiste à développer notre bibliothèque. Au lieu de nous lancer tête baissée dans sa création, nous allons réfléchir sur ce que c'est, à quoi elle doit nous servir, etc. Nous ne développerons cette bibliothèque que dans le prochain chapitre.

Ceci est une étape importante qu'il ne faut surtout pas négliger. Ne lisez donc pas ce chapitre vite fait, bien fait, sinon vous risquez d'être perdus par la suite. Par ailleurs, ne vous découragez pas si vous ne comprenez pas tout d'un coup : ce chapitre est d'un niveau plus élevé que les précédents, il est donc normal de ne pas tout comprendre dès la première lecture. Ne vous découragez pas, vous allez y arriver ! ;)

Une application, qu'est ce que c'est ?

Le déroulement d'une application

Avant de commencer à créer une application, encore faudrait-il savoir ce que c'est et en quoi cela consiste. En fait, il faut décomposer le déroulement des actions effectuées du début à la fin (le début étant la requête envoyée par le client et la fin étant la réponse renvoyée à ce client). De manière très schématique, voici le déroulement d'une application (voir la figure suivante).

Schéma simplifié du déroulement d'une application
Schéma simplifié du déroulement d'une application

Détaillons ce schéma, étape par étape.

  • Lancement de l'application : lorsque l'internaute accèdera à votre site, un fichier PHP est exécuté sur le serveur. Dans notre cas, ce fichier sera exécuté à chaque fois que le visiteur voudra accéder à une page, quelle que soit cette dernière. Que le visiteur veuille afficher une news, ouvrir un forum ou poster un commentaire, c'est ce fichier qui sera exécuté (nous verrons comment plus tard). Ce fichier sera composé de deux parties : la première aura pour rôle de gérer les différents autoloaders (nous y reviendrons), et la seconde se chargera de lancer l'application. Ce genre de fichier est appél un bootstrap.

  • Chargement de la requête du client : cette étape consiste à analyser la requête envoyée par le client. C'est lors de cette étape que l'application ira chercher les variables transmises par formulaire ou par URL (les fameuses variables GET et POST).

  • Exécution de la page désirée : c'est ici le cœur de l'exécution de l'application. Mais comment l'application connaît-elle la page à exécuter ? Quelle action le visiteur veut-il exécuter ? Veut-il afficher une news, visiter un forum, poster un commentaire ? Cette action est déterminée par ce qu'on appelle un routeur. En analysant l'URL, le routeur est capable de savoir ce que le visiteur veut. Par exemple, si l'URL entrée par le visiteur est http://www.monsupersite.com/news-12.html, alors le routeur saura que le visiteur veut afficher la news ayant pour identifiant 12 dans la base de données. Le routeur va donc retourner cette action à l'application qui l'exécutera (nous verrons plus tard ce dont il s'agit vraiment).

  • Envoi de la réponse au client : après avoir exécuté l'action désirée (par exemple, si le visiteur veut afficher une news, l'action correspondante est de récupérer cette news), l'application va afficher le tout, et l'exécution du script sera terminée. C'est à ce moment-là que la page sera envoyée au visiteur.

Pour bien cerner le principe, prenons un exemple. Si le visiteur veut voir la news n°12, alors il demandera la page news-12.html. Schématiquement, voici ce qui va se passer (voir la figure suivante).

Détails des opérations effectuées lorsqu'une page est demandée
Détails des opérations effectuées lorsqu'une page est demandée

Il est très important de comprendre ce principe. Si vous ne saisissez pas tout, n'hésitez pas à relire les explications, sinon vous risquez de ne pas suivre la suite du cours.

Vous êtes maintenant au courant qu'une application s'exécute et qu'elle a pour rôle d'orchestrer l'exécution du script afin de donner la page au visiteur. Dans un tutoriel sur la POO en PHP, je suis sûr que vous savez comment sera représentée cette application dans votre script... Oui, notre application sera un objet ! Qui dit objet dit classe, et qui dit classe dit fonctionnalités. Reprenez le schéma et énoncez-moi les fonctionnalités que possède notre classeApplication...

Pour l'instant, elle ne possède qu'une fonctionnalité : celle de s'exécuter (nous verrons par la suite qu'elle en possèdera plusieurs autres, mais vous ne pouviez pas les deviner). Cette fonctionnalité est obligatoire quelle que soit l'application : quel serait l'intérêt d'une application si elle ne pouvait pas s'exécuter ?

Dans un site web, on peut différencier 2 parties : le frontend et le backend. La première est la partie accessible par tout le monde : c'est à travers cette dernière qu'un visiteur pourra afficher une news, lire un sujet d'un forum, poster un commentaire, etc. La seconde partie est l'espace d'administration : l'accès est bloqué aux visiteurs. Pour y accéder, une paire identifiant-mot de passe est requise. Dans ce TP, nous allons séparer ces 2 parties en 2 applications distinctes. Comme vous l'aurez peut-être compris, ces deux applications seront représentées par deux classes héritant de notre classe de baseApplication.

Un peu d'organisation

Nous avons vu suffisamment de notions pour se pencher sur l'architecture de notre projet. En effet, nous savons que notre site web sera composé de deux applications (frontend et backend) ainsi que d'une classe de baseApplication.

La classeApplicationfait partie de notre bibliothèque (ou library en anglais), comme de nombreuses autres classes dont nous parlerons plus tard. Ces classes-là constituent le cœur de notre framework. Comme tout framework qui se respecte, il doit avoir un nom. Dans le cadre de ce cours, ce framework sera nommé OCFram. Les fichiers contenant les classes de notre framework seront donc dans un dossier lui étant dédié, lui-même dans le dossier qui contiendra toutes les bibliothèques (nous verrons par la suite que nous aurons besoin d'en créer d'autres). Ces classes seront donc placés dans le dossier /lib/OCFram. Je vous invite à créer ces dossiers dès maintenant.

Pour les deux applications, c'est un peu plus compliqué. En effet, une application ne tient pas dans un seul fichier : elle est divisée en plusieurs parties. Parmi ces parties, nous trouvons la plus grosse : la partie contenant les modules.

Qu'est-ce qu'un module ?

Un module est un ensemble d'actions et de données concernant une partie du site. Par exemple, les actions « afficher une news » et « commenter une news » font partie du même module de news, tandis que les actions « afficher ce sujet » et « poster dans ce sujet » font partie du module du forum.

Ainsi, je vous propose l'architecture suivante :

  • Le dossier /App contiendra nos applications (frontend et backend).

  • Le sous-dossier /App/Nomdelapplication/Modules contiendra les modules de l'application (par exemple, si l'application frontend possède un module de news, alors il y aura un dossier /App/Frontend/Modules/News).

Ne vous inquiétez pas, nous reviendrons en détail sur ces fameux modules. J'ai introduit la notion ici pour parler de l'architecture (et surtout de ce qui va suivre). En effet, vous devriez vous poser une question : quand l'utilisateur veut afficher une page, quel fichier PHP sera exécuté en premier ? Où pourrai-je placer mes feuilles de style et mes images ?

Tous les fichiers accessibles au public devront être placés dans un dossier /Web. Pour être plus précis, votre serveur HTTP ne pointera pas vers la racine du projet, mais vers le dossier /Web. Je m'explique.

Sur votre serveur local, si vous tapez localhost dans la barre d'adresse, alors votre serveur renverra le contenu du dossier C:\Wamp\www si vous êtes sous WampServer, ou du dossier /var/www si vous êtes sous LAMP. Vous êtes-vous déjà demandé comment est-ce que cela se faisait ? Qui a décrété cela ? En fait, c'est écrit quelque part, dans un fichier de configuration. Il y en a un qui dit que si on tape localhost dans la barre d'adresse, alors on se connectera sur l'ordinateur. Ce fichier de configuration est le fichier hosts. Le chemin menant à ce fichier est C:\windows\system32\drivers\etc\hosts sous Windows et /etc/hosts sous Linux et Mac OS. Vous pouvez l'éditer (à condition d'avoir les droits). Faites le test : ajoutez la ligne suivante à la fin du fichier.

127.0.0.1  monsupersite

Sauvegardez le fichier et fermez-le. Ouvrez votre navigateur, tapez monsupersite et... vous atterrissez sur la même page que quand vous tapiez localhost !

Maintenant, nous allons utiliser un autre fichier. La manipulation va consister à dire à l'ordinateur que lorsqu'on tape monsupersite, on ne voudra pas le contenu de C:\Wamp\www ou de /var/www, mais de C:\Wamp\www\monsupersite\Web si vous êtes sous Windows ou de /var/www/monsupersite/Web si vous êtes sous Linux ou Mac OS.

Tout d'abord, je vous annonce que nous allons utiliser le module mod_vhost_alias d'Apache. Assurez-vous donc qu'il soit bien activé. Le fichier que nous allons manipuler est le fichier de configuration d'Apache, à savoir httpd.conf sous WampServer. Rajoutez à la fin du fichier :

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  
  # Mettez ici le nom de domaine que vous avez utilisé dans le fichier hosts.
  ServerName monsupersite
  
  # Mettez ici le chemin vers lequel doit pointer le domaine.
  # Je suis sous Linux. Si vous êtes sous Windows, le chemin sera de la forme C:\Wamp\www\monsupersite\Web
  DocumentRoot /home/victor/www/monsupersite/Web
  <Directory /home/victor/www/monsupersite/Web>
    Options Indexes FollowSymLinks MultiViews
    
    # Cette directive permet d'activer les .htaccess.
    AllowOverride All
    
    # Si le serveur est accessible via l'Internet mais que vous n'en faites qu'une utilisation personnelle
    # pensez à interdire l'accès à tout le monde
    # sauf au localhost, sinon vous ne pourrez pas y accéder !
    deny from all
    allow from localhost
  </Directory>
</VirtualHost>

Si vous avez un serveur LAMP, n'essayez pas de trouver le fichier httpd.conf, il n'existe pas. :-°

En fait, la création d'hôtes virtuels s'effectue en créant un nouveau fichier contenant la configuration de ce dernier. Le fichier à créer est /etc/apache2/sites-available/monsupersite (remplacez monsupersite par le domaine choisi). Placez-y à l'intérieur le contenu que je vous ai donné. Ensuite, il n'y a plus qu'à activer cette nouvelle configuration grâce à la commande sudo a2ensite monsupersite (remplacez monsupersite par le nom du fichier contenant la configuration de l'hôte virtuel).

Dans tous les cas, que vous soyez sous Windows, Linux, Mac OS ou quoi que ce soit d'autre, redémarrez Apache pour que la nouvelle configuration soit prise en compte.

Essayez d'entrer monsupersite dans la barre d'adresse, et vous verrez que le navigateur vous affiche le dossier spécifié dans la configuration d'Apache !

Les entrailles de l'application

Avant d'aller plus loin, il est indispensable (voire obligatoire) de savoir utiliser le pattern MVC. Pour cela, je vous conseille d'aller lire le tutoriel Adopter un style de programmation clair avec le modèle MVC. En effet, ce cours explique la théorie du pattern MVC et je ne ferais que créer un doublon si je vous expliquais à mon tour ce motif.

Nous pouvons donc passer directement aux choses sérieuses.

Retour sur les modules

Comme je vous l'avais brièvement indiqué, un module englobe un ensemble d'actions agissant sur une même partie du site. C'est donc à l'intérieur de ce module que nous allons créer le contrôleur, les vues et les modèles.

Le contrôleur

Nous allons donc créer pour chaque module un contrôleur qui contiendra au moins autant de méthodes que d'actions. Par exemple, si dans le module de news je veux pouvoir avoir la possibilité d'afficher l'index du module (qui nous dévoilera la liste des cinq dernières news par exemple) et afficher une news, j'aurais alors deux méthodes dans mon contrôleur :executeIndex etexecuteShow. Ce fichier aura pour nom NomDuModuleController.php, ce qui nous donne, pour le module de news, un fichier du nom de NewsController.php. Celui-ci est directement situé dans le dossier du module.

Les vues

Chacune de ces actions correspond, comme vous le savez, à une vue. Nous aurons donc pour chaque action une vue du même nom. Par exemple, pour l'actionshow, nous aurons un fichier show.php. Toutes les vues sont à placer dans le dossier Views du module.

Les modèles

En fait, les modèles, vous les connaissez déjà : il s'agit des managers. Ce sont eux qui feront office de modèles. Les modèles ne sont rien d'autre que des fichiers permettant l'interaction avec les données. Pour chaque module, nous aurons donc au moins deux fichiers constituant le modèle : le manager abstrait de base (NewsManager.php) et au moins une classe exploitant ce manager (par exemple NewsManagerPDO.php). Tous les modèles devront être placés dans le dossier /lib/vendors/Model afin qu'ils puissent être utilisés facilement par deux applications différentes (ce qui est souvent le cas avec les applications backend et frontend). Cependant, ces modèles ont besoin des classes représentant les entités qu'ils gèrent. La classe représentant un enregistrement (commeNewsdans notre cas) sera, elle, placée dans le dossier /lib/vendors/Entity. Nous aurons l'occasion de faire un petit rappel sur cette organisation lors du prochain chapitre.

Le back controller de base

Tous ces contrôleurs sont chacun des back controller. Et que met-on en place quand on peut dire qu'une entité B est une entité A ? Un lien de parenté, bien évidemment ! Ainsi, nous aurons au sein de notre bibliothèque une classe abstraiteBackControllerdont héritera chaque back controller. L'éternelle question que l'on peut se poser : mais que permet de faire cette classe ? Pour l'instant, il n'y en a qu'une : celle d'exécuter une action (donc une méthode).

Je voudrais faire un petit retour sur le fonctionnement du routeur. Souvenez-vous : je vous avais dit que le routeur savait à quoi correspondait l'URL et retournait en conséquence l'action à exécuter à l'application, qui sera donc apte à l'exécuter. Cela prendra plus de sens maintenant que nous avons vu la notion de back controller. Le routeur aura pour rôle de récupérer la route correspondant à l'URL. L'application, qui exploitera le routeur, instanciera donc le contrôleur correspondant à la route que le routeur lui aura renvoyée. Par exemple, si l'utilisateur veut afficher une news, le routeur retournera la route correspondante, et l'application créera une instance deNewsControlleren lui ayant spécifié qu'il devra effectuer l'actionshow. L'application n'aura donc plus qu'à exécuter le back controller.

Souvenez-vous du schéma sur le déroulement de l'application. Si nous faisions un petit zoom sur le routeur, nous obtiendrions ceci (voir la figure suivante).

Zoom sur le routeur
Zoom sur le routeur

Vous vous posez peut-être des questions sur le contenu de la deuxième bulle associée au routeur. En fait, le routeur analyse toute l'URL et décrypte ce qui s'y cache (nous verrons plus tard comment). Quand je dis que « tout le monde pourra y accéder à travers la requête du client », c'est que nous pourrons accéder à cette valeur à travers la classe qui représentera la requête du client (que nous construirons d'ailleurs durant le prochain chapitre).

La page

Nous avons parlé jusqu'à présent du déroulement de l'application et nous avons commencé à creuser un petit peu en parlant de l'organisation interne avec l'utilisation du pattern MVC. Cependant, comment est générée la page que le visiteur aura devant les yeux ? Cette page, vous l'aurez peut-être deviné, sera représentée par une classe. Comme d'habitude, qui dit classe dit fonctionnalités. En effet, une page en possède plusieurs :

  • Celle d'ajouter une variable à la page (le contrôleur aura besoin de passer des données à la vue).

  • Celle d'assigner une vue à la page (il faut qu'on puisse dire à notre page quelle vue elle doit utiliser).

  • De générer la page avec le layout de l'application.

Des explications s'imposent, notamment sur ce que sont précisément ces vues et ce fameux layout. Le layout est le fichier contenant « l'enveloppe » du site (déclaration du doctype, inclusion des feuilles de style, déclaration des balises meta, etc.). Voici un exemple très simple :

<!DOCTYPE html>
<html>
  <head>
    <title>Mon super site</title>
    <meta charset="utf-8" />
  </head>
  
  <body>
    <?= $content ?>
  </body>
</html>

Le layout, spécifique à chaque application, doit se placer dans /App/Nomdelapplication/Templates, sous le nom de layout.php. Comme vous pouvez vous en apercevoir, il y a une variable$contentqui traîne. Vous aurez sans doute deviné que cette variable sera le contenu de la page : ce sera donc notre classePagequi se chargera de générer la vue, de stocker ce contenu dans$contentpuis d'inclure le layout correspondant à l'application.

Schématiquement, voici comment la page se construit (voir la figure suivante).

Représentation schématique de la construction d'une page
Représentation schématique de la construction d'une page

L'autoload

Voici une partie intéressante à traiter. Afin de pouvoir partager le plus facilement possible les différents codes que les développeurs écrivent, certains d'entre eux ont proposé d'établir des règles à suivre afin de suivre une structure commune dans leurs projets. Parmi ces règles, il y a PSR-0, qui est en fait un ensemble de règles dont le but est de proposer une structure à respecter de sorte à ce que tous les développeurs suivant ces recommandations puissent utiliser le même autoload. Vous pouvez consulter ces règles sur le GitHub de PHP FIG (une version française non-officielle est disponible sur php-fig.org). Voici cet ensemble de règles.

  • Les classes et les espaces de noms entièrement qualifiés doivent disposer de la structure suivante : \<Nom du Vendor>\(<Espace de noms>\)*<Nom de la Classe>.

  • Chaque espace de noms doit avoir un espace de noms racine. ("Nom du Vendor").

  • Chaque espace de noms peut avoir autant de sous-espaces de noms qu'il le souhaite.

  • Chaque séparateur d'un espace de noms est converti en DIRECTORY_SEPARATOR lors du chargement à partir du système de fichiers.

  • Chaque "_" dans le nom d'une CLASSE est converti en DIRECTORY_SEPARATOR. Le caractère "_" n'a pas de signification particulière dans un espace de noms.

  • Les classes et espaces de noms complètement qualifiés sont suffixés avec ".php" lors du chargement à partir du système de fichiers.

  • Les caractères alphabétiques dans les noms de vendors, espaces de noms et noms de classes peuvent contenir n'importe quelle combinaison de minuscules et de majuscules.

Les noms de vendors correspondent aux noms des bibliothèques : OCFram, Model et Entity par exemple.

Certains développeurs ont ainsi développé un autoloader qui sera capable de charger vos classes si vous suivez ces recommandations. Puisque nous n'aimons pas perdre du temps à réinventer la roue, nous allons directement nous en servir : il s'agit de SplClassLoader

<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the MIT license. For more information, see
 * <http://www.doctrine-project.org>.
 */
 
/**
 * SplClassLoader implementation that implements the technical interoperability
 * standards for PHP 5.3 namespaces and class names.
 *
 * http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1
 *
 *   // Example which loads classes for the Doctrine Common package in the
 *   // Doctrine\Common namespace.
 *   $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
 *   $classLoader->register();
 *
 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
 * @author Jonathan H. Wage <jonwage@gmail.com>
 * @author Roman S. Borschel <roman@code-factory.org>
 * @author Matthew Weier O'Phinney <matthew@zend.com>
 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
 * @author Fabien Potencier <fabien.potencier@symfony-project.org>
 */
class SplClassLoader
{
  private $_fileExtension = '.php';
  private $_namespace;
  private $_includePath;
  private $_namespaceSeparator = '\\';

  /**
   * Creates a new <tt>SplClassLoader</tt> that loads classes of the
   * specified namespace.
   * 
   * @param string $ns The namespace to use.
   */
  public function __construct($ns = null, $includePath = null)
  {
    $this->_namespace = $ns;
    $this->_includePath = $includePath;
  }

  /**
   * Sets the namespace separator used by classes in the namespace of this class loader.
   * 
   * @param string $sep The separator to use.
   */
  public function setNamespaceSeparator($sep)
  {
    $this->_namespaceSeparator = $sep;
  }

  /**
   * Gets the namespace seperator used by classes in the namespace of this class loader.
   *
   * @return void
   */
  public function getNamespaceSeparator()
  {
    return $this->_namespaceSeparator;
  }

  /**
   * Sets the base include path for all class files in the namespace of this class loader.
   * 
   * @param string $includePath
   */
  public function setIncludePath($includePath)
  {
    $this->_includePath = $includePath;
  }

  /**
   * Gets the base include path for all class files in the namespace of this class loader.
   *
   * @return string $includePath
   */
  public function getIncludePath()
  {
    return $this->_includePath;
  }

  /**
   * Sets the file extension of class files in the namespace of this class loader.
   * 
   * @param string $fileExtension
   */
  public function setFileExtension($fileExtension)
  {
    $this->_fileExtension = $fileExtension;
  }

  /**
   * Gets the file extension of class files in the namespace of this class loader.
   *
   * @return string $fileExtension
   */
  public function getFileExtension()
  {
    return $this->_fileExtension;
  }

  /**
   * Installs this class loader on the SPL autoload stack.
   */
  public function register()
  {
    spl_autoload_register(array($this, 'loadClass'));
  }

  /**
   * Uninstalls this class loader from the SPL autoloader stack.
   */
  public function unregister()
  {
    spl_autoload_unregister(array($this, 'loadClass'));
  }

  /**
   * Loads the given class or interface.
   *
   * @param string $className The name of the class to load.
   * @return void
   */
  public function loadClass($className)
  {
    if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {
      $fileName = '';
      $namespace = '';
      if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
      }
      $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;

      require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;
    }
  }
}

Vous pouvez dès à présent copier le contenu de cette classe dans le fichier SplClassLoader.php dans le dossier /lib/OCFram. Nous avons déjà le premier fichier de notre framework ! Pour l'utiliser, nous devrons créer une instance de cette classe et spécifier le nom du vendor ainsi que le dossier dans lequel est contenue la bibliothèque. Par exemple, pour charger automatiquement les classes de notre framework, nous ferons :

<?php
$OCFramLoader = new SplClassLoader('OCFram', '/lib');
$OCFramLoader->register();

On indique ici que le dossier de la bibliothèque OCFram (qui contiendra toutes les classes de ce vendor) se situe dans /lib.

Résumé du déroulement de l'application

Nous allons ici résumer tout ce que nous avons vu à travers un gros schéma. Je vous conseille de l'imprimer sur une feuille qui sera toujours à côté de votre écran quand vous lirez le cours : vous comprendrez mieux ce que nous serons en train de faire (voir la figure suivante).

Déroulement détaillé de l'application
Déroulement détaillé de l'application

Il est indispensable que vous compreniez ce schéma. Si vous ne voulez pas l'apprendre par cœur, imprimez-le afin de toujours l'avoir sous les yeux quand vous travaillerez sur ce projet !

Exemple de certificat de réussite
Exemple de certificat de réussite