Composer est un gestionnaire de dépendances pour php. Les dépendances sont organisées au sein d'un "package" à ne pas confondre avec les "paquets"

 

Composer permet notamment :

  • de déclarer les librairies ou packages dont le projet dépend,
  • de gérer les installation et les mises à jour de ces libraires,
  • de mettre en place facilement un "autoloader" afin que nous, développeurs php, n'ayons plus à nous soucier d'importer des fichiers via des "include" ou des "require".

Un package possède principalement :

  • un nom sour la forme "nom_du_fournisseur/nom_du_projet",
  • la liste des "packages" dont le projet dépend via la clé  "require"
  • la liste des "repositories" où aller chercher les packages. Par défaut, composer ira les chercher chez packagist.org
  • des méta-informations optionnelles :
    • un (ou plusieurs) auteurs,
    • une description,
    • un type,
    • une licence,
  • ...

Pour cela, il faut bien entendu avoir déjà installé composer. Ensuite voici la marche à suivre :

1 - Initier le projet avec composer :

composer init

Puis répondre aux questions. Principalement, il faut donner un nom à votre package. J'ai personnellement donné comme nom pour un premier test : coopernet/testautoload. Pour commencer, il faut répondre négativement aux questions  :

  • Would you like to define your dependencies (require) interactively [yes]?
  • Would you like to define your dev dependencies (require-dev) interactively [yes]? 

Sinon, vous seriez embarqués dans la recherche des dépendances (https://packagist.org/) nécessaire à votre projet en production et en développement.

Cela va générer un fichier composer.json du type :

{
    "name": "coopernet/testautoload",
    "authors": [
        {
            "name": "yvandouenel",
            "email": "y.douenel@coopernet.fr"
        }
    ],
    "require": {}
}

2 - Autoload PSR-4

Pour mettre à jour l'auto-chargement de Composer :

composer dump-autoload

Il faudra ajouter des lignes de code au fichier composer.json afin de spécifier les recommandations standard php concernant l'autoload (PSR-4). Cela décrit où placer les fichiers qui vont être "autoloadés".

Sous la clé psr-4, on définit un "mappage" des espaces de noms aux chemins, par rapport à la racine du package. Lors du chargement automatique d'une classe comme Foo\\Bar\\Baz, un préfixe d'espace de noms Foo\\ pointant vers un répertoire src/ signifie que le chargeur automatique recherchera un fichier nommé src/Bar/Baz.php et l'inclura s'il est présent. Notez que contrairement à l'ancien style PSR-0, le préfixe (Foo\\) n'est pas présent dans le chemin du fichier.

Les préfixes d'espace de noms doivent se terminer par \\ pour éviter les conflits entre préfixes similaires. Par exemple, Foo correspondrait aux classes dans l'espace de noms FooBar afin que les barres obliques inverses de fin résolvent le problème : Foo\\ et FooBar\\ sont distincts.

Dans l'exemple ci-dessous les fichiers seront à placer dans le répertoire app qui se trouve à la racine de notre projet. On utilisera le namespace App\ pour les appeler automatiquement.

{
    "name": "coopernet/testautoload",
    "authors": [
        {
            "name": "yvandouenel",
            "email": "y.douenel@coopernet.fr"
        }
    ],
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    },
    "require": {}
}

Attention, cette configuration va vous permettre de charger automatiquement les fichiers qui se trouvent directement dans le répertoire "app". Imaginons que vous ayez envie de créer une arborescence du type "app/services", il vous faudra ajouter une ligne dans le fichier composer.json :

"autoload": {
        "psr-4": {
            "App\\": "app/",
            "App\\Services\\": "app/services"
        }
    },

Si on a besoin qu'un même préfixe cherche dans plusieurs répertoires, on peut alors spécifier un tableau :

{
    "autoload": {
        "psr-4": { "App\\": ["app/", "lib/"] }
    }
}


Si on veut définir un répertoire de secours (fallback directory) dans lequel tout espace de noms sera recherché, on peut utiliser un préfixe vide :

{
    "autoload": {
        "psr-4": { "": "src/" }
    }
}

Pour mettre à jour l'auto-chargement de Composer :

composer dump-autoload

3 - Création du fichier vendor/autoload.php

composer dump-autoload

Cela va créer le fichier autoload.php dans le répertoire vendor. Par convention, toutes les applications tierces (le code qui provient d'autres dévelopeurs) se trouvent dans le répertoire "vendor". Si cela peut vous aider, c'est pour moi le répertoire où se trouve le "vendeur" d'applications (ou dépendances). Un vendeur sympathique puisque ses produits sont "gratuits", tout au moins dans le monde du logiciel libre ! En fait la traduction la plus adaptée serait sans doute "fournisseur". Pour le dire autrement, se trouvent donc dans ce répertoire tous les fichiers "fournis" par des tiers.

C'est dans ce fichier php qui fait appel à vendor/autoload_real.php que va se trouver l'implémentation de la logique qui va faire en sorte que l'import des fichiers se fasse automatiquement.

4 - Chargement de l'autooad

Dans le fichier principal de votre projet, index.php par convention, ajouter la ligne suivante :

require 'vendor/autoload.php';

Arborescence complète

Au final, l'arborescence de mon exemple est la suivante :

autoload php

Détail du fichier à la racine index.php

<?php
require 'vendor/autoload.php';
use App\Card;
$card = new Card("Nom de l'inventeur du web ?", "Tim Berners-Lee");
?>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Affichage d'une instance de classe</title>
</head>
<body>
  <?php
  echo <<<EOT
  <dl>
    <dt>Question</dt>
    <dd>$card->question </dd>
    <dt>Réponse</dt>
    <dd>$card->answer </dd>
</dl>
EOT;
?>
<dt>Date</dt>
<dd><?= $card->date->format('Y-m-d H:i:s') ?></dd>
  
</body>
</html>

Détail du fichier  app/Card.php

<?php
namespace App;
class Card {
  // déclaration d'une propriété
  public $test = "test avec autoload";

  function __construct($question, $answer) {
    $this->question = $question;
    $this->answer = $answer;
    $this->date = new \DateTime();
  }

  // déclaration des méthodes
  public function dumpQuestion() {
    echo $this->question;
  }
}

Extension Visual Studio Code

Pour vous aider dans l'utilisation de vos "namespace", vous pouvez utiliser l'extension "PHP Namespace Resolver" de Visual Studio Code. 

Placer vous sur la "class" que vous souhaitez appeler (ici Card dans le fichier index.php) puis F1 > import class et cela va automatiquement écrire l'appel du bon namespace en haut de votre fichier (use App\Card;). Vous pouvez également utiliser un raccourci clavier qui dépendra de votre système d'exploitation (Ctrl + Alt + I par défaut mais dans mon système, ce raccourci clavier est déjà utilisé).