Packager son code dans une archive PHP: PHAR

Apparu avec PHP 5.3, notre language préféré (enfin le mien) propose de packager son code dans une archive Phar tout comme java le propose avec les Jar. De mon expèrience c'est Composer qui le premier m'a fait utiliser les phar, suivie par PHPUnit et tous les outils de contrôle qualité du code. Ce n'est que très récemment que j'ai commencé à avoir l'utilité de packager mon code dans des fichiers phar. Et il faut reconnaitre qu'avoir un seul fichier à déployer sur plusieurs servers est tout de même plus pratique qu'un dossier et on gagne également tout le temps de configuration/installation des vendors entre autre.

Au début j'ai voulu créer moi même le phar pour mon projet via l'API Phar de PHP. Mais c'est un peu un travail de titan. J'ai donc cherché comment être plus efficace, il y a pas mal d'outils sur Github qui permettent de créer plutôt facilement un Phar. J'ai choisi clue/phar-composer pour sa simplicité. Comme son nom l'indique, cet outil utilise composer et il faut donc un fichier composer.json à la racine du projet pour l'utiliser. 

J'ai réalisé un petit programme qui me permet de valider la compléxitée des mots de passe d'utilisateur. Pas inspiré, j'ai appelé ce projet crackme. Voici à quoi ressemble le fichier composer.json:

 
{
  "name": "crackme",
  "license": "proprietary",
  "type": "project",
  "autoload": {
    "psr-4": {
      "": "src/"
    }
  },
  "require": {
    "php": ">=5.4.0",
    "symfony/console": "~2.7",
    "symfony/yaml": "~2.7",
    "monolog/monolog": "~1.17",
    "doctrine/dbal": "~2.5",
    "swarrot/swarrot": "~2.1",
    "videlalvaro/php-amqplib": "~2.5"
  },
  "bin": ["crackme"]
}
 

Ce qui est important ici, c'est la dernière ligne, j'indique mon exécutable, un script php, mais sans son extension. Le fichier doit avoir les droits d'exécutions.


Mon fichier crackme ressemble à:

 
#!/usr/bin/env php
<?php
 
require_once __DIR__ . '/vendor/autoload.php';
 
use Symfony\Component\Console\Application;
use Crackme\Command\CrackIt;
 
define('ROOT_PATH', realpath('.'));
 
$application = new Application('Crack me', '1.0-dev');
$application->add(new CrackIt());
$application->run();
 

Sur la première ligne du fichier, je précise l'interpréteur qui doit être utilisé.
A l'interieur d'un phar, la racine n'est plus la racine du disque dur mais la racine à l'interieur du phar; ce qui ne pose aucun problème pour accéder aux fichiers dans le phar mais complique les choses pour ceux à l'exterieur. J'ai donc définis la constante ROOT_PATH sur le path courant pour avoir une référence du chemin sur le disque dur où est mon phar.

Le reste de mon code est dans le dossier src/ mais pourrait être à la racine et n'a rien de spécifique par rapport au fait qu'il va être utilisé dans un phar.

Pour compiler le phar j'ai besoin de phar-composer que j'ai téléchargé  et bien sûr de Composer sur ma machine. J'ai fait un lien symbolique de composer dans /usr/bin sous le nom "composer". Composer-phar cherche à y accéder dans le cas où les vendors ne sont pas installés et doivent l'être. Il ne reste plus qu'à lancer le build.

 
 php -d phar.readonly=off ./phar-composer.phar build ./crackme/

Il faut désactiver la lecture seule sur les phar dans php.ini, mais ne voulant pas le faire globalement sur la machine, je le spécifie dans ma ligne de commande. Après quelques logs, la compilation se termine et j'obtiens un fichier crackme.phar que je peux executer sans avoir à lui passer l'interpréteur.

Il existe d'autres options, d'autres outils pour créer des phar, tout dépend de votre besoin, le mien étant plutôt basique phar-composer y répond très bien. Depuis cette première expèrience, je multiplie l'utilisation des phar.

 

Il n'y aucun commentaire