Licence CC BY-NC-SA

Installer un bundle grâce à Composer

Je fais une parenthèse pour vous présenter un chapitre sur l'outil Composer.

Cet outil ne fait absolument pas partie de Symfony2, mais son usage est tellement omniprésent dans la communauté Symfony2 que je me dois de vous le présenter. Nous faisons donc une pause dans le développement de notre blog pour parler un peu de cet outil de gestion de dépendances, qui va nous servir à installer des bundles et autres bibliothèques très facilement.

Bonne lecture !

Composer, qu'est-ce que c'est ?

Un gestionnaire de dépendances

Composer est un outil pour gérer les dépendances en PHP. Les dépendances, dans un projet, ce sont toutes les bibliothèques dont votre projet dépend pour fonctionner. Par exemple, votre projet utilise la bibliothèque SwiftMailer pour envoyer des e-mails, il « dépend » donc de SwiftMailer. Autrement dit, SwiftMailer est une dépendance dans votre projet.

Composer a donc pour objectif de vous aider à gérer toutes vos dépendances. En effet, il y a plusieurs problématiques lorsqu'on utilise des bibliothèques externes :

  • Ces bibliothèques sont mises à jour. Il vous faut donc les mettre à jour une à une pour vous assurer de corriger les bogues de chacune d'entre elles.
  • Ces bibliothèques peuvent elles-mêmes dépendre d'autres bibliothèques. En effet, si une de vos bibliothèques dépend d'autres bibliothèques, cela vous oblige à gérer l'ensemble de ces dépendances (installation, mises à jour, etc.).
  • Ces bibliothèques ont chacune leur paramètres d'autoload, et vous devez gérer leur autoload pour chacune d'entre elles.

Composer va nous aider dans chacune de ces tâches.

Comment Composer sait où trouver les bibliothèques ?

Très bonne question. En effet, il est évident que ce système de gestion ne peut marcher que si on peut centraliser les informations de chaque bibliothèque. Il s'agit du site www.packagist.org.

Par exemple, voici la page pour la bibliothèque Symfony2 (eh oui, c'est une bibliothèque comme une autre !) : https://packagist.org/packages/symfony/symfony. Vous pouvez voir les informations comme le mainteneur principal, le site de la bibliothèque, etc. Mais ce qui nous importe le plus, ce sont les sources ainsi que les dépendances (dans Requires).

Composer va donc lire ces informations, et a alors toutes les cartes en main pour télécharger Symfony2 ainsi que ses dépendances.

Un outil innovant… dans l'écosystème PHP

Ce genre d'outil de gestion de dépendances n'est pas du tout nouveau dans le monde informatique. Vous connaissez peut-être déjà APT, le gestionnaire de paquets de la distribution Linux Debian. Il existe également des outils de ce genre pour le langage Ruby par exemple. Cependant, jusque très récemment, il n'existait aucun outil de ce genre pour PHP. La forte communauté qui s'est construite autour de Symfony2 a fait naître le besoin d'un tel outil, et l'a ensuite développé.

Concrètement, comment ça marche ?

Concrètement, voici comment s'utilise Composer :

  • On définit dans un fichier la liste des bibliothèques dont le projet dépend, ainsi que leur version ;
  • On exécute une commande pour installer ou mettre à jour ces bibliothèques (et leurs propres dépendances donc) ;
  • On inclut alors le fichier d'autoload généré par Composer dans notre projet.

Mais avant de manipuler Composer, commençons par l'installer !

Installer Composer et Git

Installer Composer

Installer Composer est très facile, il suffit d'une seule commande… PHP ! Exécutez cette commande dans la console :

1
C:\wamp\www> php -r "eval('?>'.file_get_contents('http://getcomposer.org/installer'));"

Cette commande va télécharger et exécuter le fichier PHP suivant : http://getcomposer.org/installer . Vous pouvez aller le voir, ce n'est pas Composer en lui-même mais son installateur. Il fait quelques vérifications (version de PHP, etc.), puis télécharge effectivement Composer dans le fichier composer.phar.

Composer en lui-même, c'est le fichier PHAR composer.phar, c'est lui que nous devrons exécuter par la suite. Vous pouvez déjà l'exécuter pour vérifier que tout est OK :

1
2
C:\wamp\www>php composer.phar --version
Composer version a5eaba8

N'hésitez pas à mettre à jour Composer lui-même de temps en temps. Il faut pour cela utiliser la commande self-update de Composer, comme suit :

1
2
3
C:\wamp\www>php composer.phar self-update
Updating to version ded485d.
    Downloading: 100%

Et voilà, je viens de mettre à jour Composer très simplement !

Cependant, l'installation n'est pas finie. En effet, pour récupérer certaines bibliothèques, Composer utilise Git.

Installer Git

Comme on l'a vu, pour récupérer les bibliothèques, Composer se base sur les informations répertoriées sur Packagist. Si pour certaines bibliothèques Composer peut télécharger directement des archives contenant les sources, pour d'autres il doit utiliser un gestionnaire de versions tel que Git.

En réalité, beaucoup de bibliothèques sont dans ce cas, c'est pourquoi l'installation de Git ne peut être évitée. Ce n'est pas grave, attaquons-la ! Je vais ici décrire rapidement son installation, mais sachez qu'un cours du Site du Zéro détaille très bien son fonctionnement et son installation.

Installer Git sous Windows

Sous Windows, il faut utiliser msysgit. Cela installe msys (un système d'émulation des commandes Unix sous Windows) et Git lui-même.

Téléchargez le fichier et exécutez-le, cela va tout installer. Laissez les paramètres par défaut, ils conviennent très bien. Cela va prendre un peu de temps, car il y a pas mal à télécharger (une centaine de Mo) et à exécuter, ne vous inquiétez pas. Une fois que vous avez une ligne de commande (/dev), vous pouvez fermer la fenêtre.

Une fois cela installé, il faut ajouter les exécutables Git au PATH de Windows. Ajoutez donc ceci : « ;C:\msysgit\bin;C:\msysgit\mingw\bin » à la suite de votre variable d'environnement système PATH (on en a déjà parlé dans le premier chapitre).

Redémarrez votre ordinateur, et ensuite vérifiez l'installation en exécutant la commande suivante :

1
2
C:\wamp\www>git version
git version 1.7.9.msysgit.0

Si vous n'avez pas d'erreur, c'est tout bon !

Installer Git sous Linux

Sous Linux, c'est encore plus simple avec votre gestionnaire de paquets. Voici comment l'installer depuis la distribution Debian et ses dérivées (Ubuntu, etc.) :

1
sudo apt-get install git-core

Installer un bundle grâce à Composer

Manipulons Composer

Avant d'utiliser Composer dans notre projet Symfony2, on va d'abord s'amuser avec lui sur un projet test afin de bien comprendre son fonctionnement. Créez donc un répertoire test là où vous avez téléchargé Composer.

Déclarer ses dépendances

La première chose à faire dans un projet, c'est de déclarer ses dépendances. Cela se fait via un fichier composer.json, qui contient les informations sur les bibliothèques dont dépend votre projet ainsi que leur version. La syntaxe est assez simple, en JSON, créez le fichier suivant :

1
2
3
4
5
6
7
// test/composer.json

{
  "require": {
    "twig/extensions": "dev-master"
  }
}

Ce tableau JSON est le minimum syndical : il ne précise que les dépendances via la clé require. Il n'y a ici qu'une seule dépendance : "twig/extensions". La version requise pour cette dépendance est "dev-master", cela signifie qu'on veut la version la plus à jour possible.

Un point sur les versions, voici ce que vous pouvez mettre :

Valeur

Exemple

Description

Un numéro de version exact

"2.0.17"

Ainsi, Composer téléchargera cette version exacte.

Une plage de versions

">=2.0,<3.0"

Ainsi, Composer téléchargera la version la plus à jour, à partir de la version 2.0 et en s'arrêtant avant la version 3.0. Par exemple, si les dernières versions sont 2.9, 3.0 et 3.1, Composer téléchargera la version 2.9.

Un numéro de version avec joker « * »

"2.0.*"

Ainsi, Composer téléchargera la version la plus à jour qui commence par 2.0. Par exemple, il téléchargerait la version 2.0.17, mais pas la version 2.1.1. C'est la façon la plus utilisée pour définir la version des dépéndances.

Dans notre cas, "dev-master" correspond à un numéro de version exact : le dernier disponible. C'est un cas particulier.

Pour information, vous pouvez aller regarder les informations de cette bibliothèque sur Packagist. Vous pouvez voir qu'elle dépend d'une autre bibliothèque, "twig/twig", qui correspond au moteur de templates Twig à proprement parler. Il en a besoin dans sa version "1.*", Composer ira donc chercher la dernière version dans la branche 1.*.

Mettre à jour les dépendances

Pour mettre à jour toutes les dépendances, "twig/extensions" dans notre cas, il faut exécuter la commande update de Composer, comme ceci :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
C:\wamp\www\test>php ../composer.phar update
Loading composer repositories with package information
Updating dependencies
  - Installing twig/twig (v1.10.0)
    Downloading: 100%

  - Installing twig/extensions (dev-master dcdff02)
    Cloning dcdff02fbac1282e6b8f4d0558cc7e9580105688

Writing lock file
Generating autoload files

Chez moi, j'ai placé Composer (le fichier composer.phar) dans le répertoire www. Or ici on travaille dans le répertoire de test www\test. J'ai donc dit à PHP d'exécuter le fichier ../composer.phar, mais bien sûr si le vôtre est dans le répertoire courant ou ailleurs, adaptez la commande. ;)

Et voilà !

Vous pouvez aller vérifier dans le répertoire test/vendor :

  • Composer a téléchargé la dépendance "twig/extensions" que l'on a défini, dans vendor/twig/extensions ;
  • Composer a téléchargé la dépendance "twig/twig" de notre dépendance à nous, dans vendor/twig/twig ;
  • Composer a généré les fichiers nécessaires pour l'autoload, allez vérifier le fichier vendor/composer/autoload_namespaces.php.

Tout est maintenant OK pour se servir de "twig/extensions" dans votre projet ! C'était donc la démarche et le fonctionnement pour la gestion des dépendances avec Composer. Mais revenons maintenant à notre projet sous Symfony2.

Mettons à jour Symfony2

Ce paragraphe s'adresse à ceux qui ont téléchargé l'archive « with vendors » de Symfony2, et qui ne l'ont pas déjà téléchargée via Composer.

Si vous avez téléchargé la version de Symfony2 qui comprend déjà les dépendances, vous avez en fait téléchargé tout le contenu du dossier vendor que Composer pourrait gérer tout seul. L'objectif de ce paragraphe est de déléguer cette gestion à Composer.

Vous pouvez voir qu'en fait il existe déjà un fichier de définition des dépendances à la racine de votre projet : le fichier composer.json. N'hésitez pas à l'ouvrir : vous pourrez y voir toutes les dépendances déjà définies.

Pour l'instant, ce fichier existe, mais on n'a jamais utilisé Composer pour les gérer. Il ne reste donc plus qu'à dire à Composer de les mettre toutes à jour. Rien de spécial à faire par rapport à tout à l'heure, exécutez simplement la commande suivante :

1
php ../composer.phar update

Cela va prendre un peu de temps, car Composer a beaucoup à télécharger, les dépendances d'un projet Symfony2 sont nombreuses. Il y a en effet Symfony2 en lui-même, mais également Doctrine, Twig, certains bundles, etc.

Maintenant, Composer a pris la main sur toutes vos dépendances, on va pouvoir en ajouter une nouvelle : un bundle Symfony2 !

Installer un bundle avec Composer

Dans ce paragraphe, nous allons installer le bundle DoctrineFixtureBundle, qui permet de préremplir la base de données avec des données, afin de bien tester votre application. Cependant, les explications sont valables pour l'installation de n'importe quel bundle, retenez donc bien la méthode.

1. Trouver le nom du bundle

Vous l'avez compris, on définit une dépendance dans Composer via son nom. Il faut donc logiquement connaître ce nom pour pouvoir l'installer. Pour cela, rien de plus simple, on se rend sur http://packagist.org/ et on fait une petite recherche. Dans notre cas, recherchez « fixture », et cliquez sur le bundle de Doctrine, « doctrine/doctrine-fixtures-bundle ».

2. Déterminer la version du bundle

Une fois que vous avez trouvé votre bundle, il faut en sélectionner une version. Il se peut que celui-ci n'ait pas vraiment de version fixe, et que seul "dev-master" soit disponible. Dans ce cas, assurez vous (auprès du développeur, ou en regardant le code) qu'il est compatible avec votre projet.

Mais la plupart du temps, les bundles sont versionnés et c'est à vous de choisir la version qui vous convient. Restons sur notre cas du bundle fixture : https://packagist.org/packages/doctrine/doctrine-fixtures-bundle . Les deux dernières versions sont "dev-master" et "2.0.x-dev" :

  • Regardez les prérequis de la version 2.0.x-dev : il est indiqué que cette version a besoin de "symfony/symfony" dans sa version 2.0 (car "<2.1" exclut la version 2.1). Cette version est trop vieille, on ne peut donc pas l'utiliser, car on tourne sur un Symfony 2.2 ;
  • Regardez alors les prérequis de la version dev-master : on a besoin de "doctrine/doctrine-bundle" (cliquez dessus), qui lui-même a besoin de "symfony/framework-bundle" dans sa version 2.1 ou 2.2 ("<2.3" exclut la 2.3, rappelez-vous). Ce bundle suit la même numérotation de version que le framework Symfony2, la version 2.2 est donc OK pour nous.

On choisit alors la version "dev-master" du bundle.

3. Déclarer le bundle à Composer

Une fois qu'on a le nom du bundle et sa version, il faut le déclarer à Composer, dans le fichier composer.json. On sait déjà le faire, il faut modifier la section "require", voici ce que cela donne :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// composer.json

// …

"require": {
  "php": ">=5.3.3",
  // …
  "jms/di-extra-bundle": "1.1.*",
  "doctrine/doctrine-fixtures-bundle": "dev-master",
  "doctrine/data-fixtures": "@dev"
},

// …

Nous avons affaire à un cas particulier. Notre Composer est paramétré pour ne prendre que des versions stables, sauf si on le lui dit explicitement. Avec twig/extensions et maintenant doctrine/doctrine-fixtures-bundle, on a explicitement précisé qu'on voulait une version de développement ("dev-master"). Or, si tout à l'heure toutes les dépendances de twig/extensions existaient en version stable, ce n'est pas le cas de doctrine/doctrine-fixtures-bundle : la dépendance doctrine/data-fixtures n'existe pas encore en version stable. On est donc obligé de dire à Composer qu'on accepte les versions de développement de cette dépendances : d'où la ligne doctrine/data-fixtures: "@dev". Le "@dev" signifie qu'on ne précise pas de numéro de version exacte, mais qu'on accepte également les versions de développement.

N'oubliez pas d'ajouter une virgule à la fin de l'avant-dernière dépendance, dans mon cas "jms/di-extra-bundle" !

4. Mettre à jour les dépendances

Une fois la dépendance déclarée à Composer, il ne reste qu'à mettre à jour les dépendances, avec la commande update :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
C:\wamp\www\Symfony>php ../composer.phar update
Loading composer repositories with package information
Updating dependencies
  - Installing doctrine/data-fixtures (dev-master a95d783)
    Cloning a95d7839a7794c7c9b22d64e859ee70658d977fe

  - Installing doctrine/doctrine-fixtures-bundle (dev-master 9edc67a)
    Cloning 9edc67af16e736a31605e7fa9c9e3edbd9db6427

Writing lock file
Generating autoload files
Clearing the cache for the dev environment with debug true
Installing assets using the hard copy option
[…]

5. Enregistrer le bundle dans le Kernel

Dernier point, totalement indépendant de Composer : il faut déclarer le bundle dans le Kernel de Symfony2. Allez dans app/AppKernel.php et ajoutez la ligne 8 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
// app/AppKernel.php

// …

  if (in_array($this->getEnvironment(), array('dev', 'test'))) {
    // ...
    $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
  }

// …

Ici, j'ai déclaré le bundle uniquement pour les modes « dev » et « test », car c'est l'utilité du bundle fixture, on en reparlera. Bien entendu, si votre bundle doit être accessible en mode « prod », placez-le en conséquence. ;)

Voilà, votre bundle est opérationnel !

Attention si vous avez l'habitude de Symfony2.0 où il fallait également déclarer le namespace pour l'autoload : perdez cette habitude tout de suite ! Composer s'occupe vraiment de tout, et notamment de déclarer les namespaces pour l'autoload : allez le vérifier dans le fichier vendor/composer/autoload_namespaces.php. Ce fichier contient tous les namespaces nécessaires pour votre projet, et Symfony2 l'inclut déjà, vérifiez-le en regardant le fichier app/autoload.php, on y voit cette ligne :

1
2
3
<?php
if (!$loader = @include __DIR__.'/../vendor/autoload.php') {
// …

Voilà comment Symfony2 utilise Composer pour gérer son autoload.

Gérer l'autoload d'une bibliothèque manuellement

Il se peut que vous ayez une bibliothèque existante en stock, mais qui n'est pas référencée sur Packagist. Composer ne peut pas gérer entièrement cette bibliothèque, car il n'a pas ses informations : comment la mettre à jour, quelles sont ses dépendances, etc.

Par contre, vous avez tout de même envie de l'intégrer dans votre projet. Notamment, vous souhaitez la charger automatiquement grâce à l'autoload PHP. Pour ce faire, il faut ajouter la section "autoload" à votre composer.json, dans laquelle Composer ne mettra pas son nez pour tout ce qui est installation et mises à jour. Par contre, il l'inclura dans son fichier d'autoload que Symfony2 charge. Voici ce que vous devez rajouter :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// composer.json

{
  // …

  "autoload": {
    "psr-0": {
      "VotreNamespace": "chemin/vers/la/bibliotheque"
    }
  }

  // …
}

Attention, il faut toujours utiliser cette méthode et ne jamais aller modifier le fichier vendor/composer/autoload_namespaces.php ! Comme tout fichier qui se trouve dans le répertoire vendor, vous ne devez pas le toucher, car il peut être écrasé à tout moment : dès que vous faites un update avec Composer, ce dernier va télécharger les nouvelles versions et écraser les anciennes…

Bien sûr, pour que cela fonctionne il faut que votre bibliothèque respecte la convention PSR-0, c'est-à-dire une convention de nommage et d'autoloading. Je vous invite à lire le lien pour en savoir plus à ce propos. Symfony2 suit bien entendu cette convention.

Pour conclure

Ce chapitre-parenthèse sur Composer touche à sa fin. S'il vous semble un peu décalé aujourd'hui, vous me remercierez un peu plus tard de vous en avoir parlé, lorsque vous voudrez installer des bundles trouvés à droite ou à gauche. D'ailleurs, on a déjà installé DoctrineFixtureBundle, un bundle bien pratique dont nous nous resservirons dès la prochaine partie sur Doctrine !

Sachez également que je n'ai absolument pas tout dit sur Composer, car cela ferait trop long et ce n'est pas tellement l'objet de ce tutoriel. Cependant, Composer a sa propre documentation et je vous invite à vous y référer. Par curiosité, par intérêt, en cas de problème, n'hésitez pas : http://getcomposer.org !


En résumé

  • Composer est un outil pour gérer les dépendances d'un projet en PHP, qu'il soit sous Symfony2 ou non.
  • Le fichier composer.json permet de lister les dépendances que doit inclure Composer dans votre projet.
  • Composer détermine la meilleure version possible pour vos dépendances, les télécharge, et configure leur autoload tout seul.
  • Composer trouve toutes les bibliothèques sur le site http://www.packagist.org, sur lequel vous pouvez envoyer votre propre bibliothèque si vous le souhaitez.
  • La très grande majorité des bundles Symfony2 sont installables avec Composer, ce qui simplifie énormément leur utilisation dans un projet.