Utiliser Phar pour packager un projet
Sommaire
Construire son archive Phar
Script de construction
Créer un make-archive.php comme suit :
<?php $path = $_SERVER['argv'][2].'e-venement.phar.php'; if ( file_exists($path) ) unlink($path); $phar = new Phar($path, NULL, 'e-venement.phar.php'); $phar->buildFromDirectory($_SERVER['argv'][1]); $phar->setStub("<?php Phar::mapPhar('e-venement.phar.php'); Phar::webPhar(); Phar::mungServer(); Phar::interceptFileFuncs(); __HALT_COMPILER(); ?>"); $phar->stopBuffering();
Et appelez-le via la commande :
$ php -d phar.readonly=0 make-archive.php [RÉPERTOIRE À PACKAGER]
Si vous avez des répertoires où vous aurez à écrire des données
Utiliser la commande :
Phar::mount('/writable/path/cache/', 'phar://e-venement.phar.php/cache/');
Ainsi, toutes les écritures dans ./cache (dans l'archive) seront envoyées dans /writable/path/cache/ (équivalent d'un mount UNIX).
Placez cette commande (au choix) :
- dans un fichier chargé en début d'exécution de votre application
- dans un fichier que vous aurez créé spécialement et qui sera chargé avant (ou au tout début de) chaque exécution de votre application
- dans un stub de votre archive Phar
Les commandes à oublier / remplacer
realpath()
À remplacer par la fonction suivante :
function realpath2($path) { // whether $path is unix or not $unipath = strlen($path)==0 || $path{0}!='/'; $unc = substr($path,0,2)=='\\\\'?true:false; // attempts to detect if path is relative in which case, add cwd if(strpos($path,':') === false && $unipath && !$unc){ $path=getcwd().DIRECTORY_SEPARATOR.$path; if($path{0}=='/'){ $unipath = false; } } // resolve path parts (single dot, double dot and double delimiters) $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutes = array(); foreach ($parts as $part) { if ('.' == $part){ continue; } if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } $path = implode(DIRECTORY_SEPARATOR, $absolutes); // resolve any symlinks if( function_exists('readlink') && file_exists($path) && linkinfo($path)>0 ){ $path = readlink($path); } // put initial separator that could have been lost $path = !$unipath ? '/'.$path : $path; $path = $unc ? '\\\\'.$path : $path; // TODO $path = str_replace('phar:', 'phar://', $path); return $path; }
getcwd()
Utiliser la constante __DIR__ à la place.
e-venement ou un autre projet Symfony1
Se dotter d'un script make-archive.php adapté
Symfony1 requiert la possibilité de lancer des tâches depuis la ligne de commande "CLI". Il faut donc se permettre de lancer ces commandes depuis l'extérieur de la Phar.
Rajoutez donc ces éléments dans votre fichier make-archive.php :
// ... Phar::mapPhar('e-venement.phar.php'); if ( isset(\$_SERVER['argv']) ) if ( \$_SERVER['argv'][1] == './symfony' ) { \$php = 'phar://e-venement.phar.php/'.\$_SERVER['argv'][1]; foreach ( \$_SERVER['argv'] as \$i => \$arg ) if ( \$i > 1 ) \$_SERVER['argv'][\$i-1] = \$arg; array_pop(\$_SERVER['argv']); require \$php; die(); } Phar::webPhar(); // ...
Se créer une instance initiale
Prendre un déploiement fonctionnel d'e-venement (fichiers de configuration inclus) et le recopier ainsi :
$ cp -Lr [REPSOURCE] [REPDESTINATION]
Cela élimine tous les problèmes liés aux liens symboliques...
Les problèmes de path
1. Remplacer tous les appels à realpath() par realpath2() 2. Remplacer tous les appels à getcwd() par __DIR__ 3. Retirer la première ligne du fichier ./symfony (#!/usr/bin/php)
Répertoires cache et log
Rajouter un paramétrage particulier pour les répertoires de cache, de log, etc... dans votre fichier config/ProjectConfiguration.php :
public function setup() { $this->setCacheDir('/tmp/myproject/cache'); $this->setLogDir('/tmp/myproject/log'); // ... }