En route vers PHP 5.5 : Installation d'une version de test (sous linux)

19 novembre 2012php, php-5.5
 Cet article a été rédigé il y a plusieurs années et peut ne plus être tout à fait à jour…

J’ai parlé plusieurs fois ce dernier mois de nouveautés apportées par ce qui est en train de devenir PHP 5.5… Mais la meilleure façon de découvrir celles-ci n’est-elle pas d’expérimenter, de les utiliser depuis vos scripts et applications ?

Avec la sortie de la première version alpha il y a quelques jours, c’est aussi l’occasion de commencer à vérifier le bon fonctionnement de vos applications – et, si besoin est, de rapporter des bugs.

Pour faciliter un peu les choses, voici quelques notes que j’ai pris en installant un des environnements de test que j’ai moi-même utilisé pour expérimenter, et écrire ces quelques articles. Au moment où j’ai commencé à rédiger cet article, la première version alpha n’était pas encore sortie, et je compilais régulièrement la branche master de PHP depuis son repository git ; depuis, j’ai ajouté quelques informations quant à la compilation d’une version packagée, comme la version alpha-1.

Installer une version de développement / test de PHP ?

Le but de cet article est de présenter une façon possible d’installer la version de développement courante de PHP, ou une version de test (comme une release alpha/beta/RC) ; opération que vous pouvez vouloir réaliser sur un environnement de test ou de développement, éventuellement sur une machine virtuelle – et jamais sur un serveur de production1 !

Le gros des développements aujourd’hui, mis à part d’éventuelles corrections de bugs et/ou évolutions mineures sur PHP 5.3 et PHP 5.4, se concentrent sur la branche master du repository git hébergeant les sources de PHP – et, depuis la création de la branche PHP-5.5, ceux destinés à être intégrés à PHP 5.5 arrivent jusqu’à cette branche.

En fonction de la version que vous voulez tester, vous pouvez extraire depuis le repository git la branche de PHP qui vous intéresse :

  • master pour les tous derniers développements ; possiblement même des fonctionnalités qui ne seront pas intégrées à PHP 5.5 et qui pourraient n’arriver qu’avec la version suivante
  • PHP-5.5, PHP-5.4, PHP-5.3, … pour les développements correspondant à une version mineure donnée,
  • Ou même des versions release, avec des branches comme PHP-5.4.9, PHP-5.3.19, …

Tout de même, en particulier si vous vous préparez à tester PHP 5.5 alors que la première version alpha vient tout juste de sortir, rappelez-vous que rien n’est figé dans le marbre tant qu’une version est encore en développement et n’est pas sortie en version stable !.

Obtenir les sources de PHP

A partir du moment où nous souhaitons compiler PHP depuis ses sources, deux options s’offrent à nous :

  • Extraire les sources depuis le repository git les hébergeant,
  • Ou utiliser un package contenant les sources d’une version spécifique de PHP.

Obtenir les sources de PHP depuis git

Cette section correspond au cas où vous voulez compiler et tester les tous derniers développements destinés à une future version de PHP – et pas une version packagée comme une alpha/beta/RC (même si, bien sûr, il est possible de construire une telle version depuis le tag git qui va bien).

Les sources de PHP sont hébergées sur un repository git.

La solution pour installer une version de développement de PHP, non packagée sous forme d’archive téléchargeable, est donc :

  • d’extraire les sources depuis la branche qui vous intéresse – ici, je partirai du principe que nous voulons travailler avec la branche PHP-5.5,
  • de configurer la compilation,
  • et d’effectuer celle-ci,
  • avant de déployer les binaires obtenus,
  • et de configurer quelques éléments.

Pour obtenir les sources de PHP, tout d’abord, il faut récupérer les sources depuis le repository git qui les héberge2 :

git clone https://git.php.net/repository/php-src.git
cd php-src

A titre d’information, vous pouvez lister toutes les branches existantes (vous constaterez en particulier qu’il en existe une pour chaque version du langage) :

git branch -a

Si on regarde avec un outil graphique (j’ai utilisé qgit, ici, mais vous obtiendriez quelque chose d’équivalent avec un autre programme – y compris avec git log en ligne de commandes), nous avons accès à l’historique des commits sur PHP.
Par exemple, ici, j’ai sélectionné le moment où les développements autour des Generators ont été mergés vers la branche master :

Capture d'écran de qgit

La branche PHP-5.5 a été créée il y a quelques jours, et correspond aux développements destinés à (assez probablement, même si certains points peuvent encore évoluer) figurer dans la prochaine version de PHP – celle que nous voulons tester.

Passons donc sur cette branche :

git checkout PHP-5.5

Ici, puisque nous avons extrait les sources brutes depuis le repository de développement, le script configure n’existe pas, et nous allons devoir le créer à l’aide de la commande buildconf :

$ ./buildconf 
buildconf: checking installation...
buildconf: autoconf version 2.68 (ok)
rebuilding aclocal.m4
rebuilding configure
rebuilding main/php_config.h.in

Une fois ceci fait, nous allons pouvoir lancer le script configure – rendez-vous un peu plus bas ;-)

Obtenir les sources d’une version packagée de PHP

Cette section correspond au cas où voulez compiler et tester une version packagée de PHP, comme une alpha/beta/RC ou même une version stable – et pas extraire depuis le repository git de PHP les sources correspondant aux tous derniers développements.

A chaque fois qu’une version de test est taggée, les sources correspondantes sont disponibles sous forme d’une archive .tar.gz ou .tar.bz2 (ou .tar.xz depuis PHP 5.5) sur la page de l’équipe PHP Quality Assurance.

Deux choses à faire :

  • Télécharger une des archives correspondant à la version qui nous intéresse,
  • et décompresser cette archive.

Typiquement, cela peut se résumer aux quelques commandes suivantes (si vous souhaitez tester une autre version que l’alpha1, comme l’alpha2 qui sortira dans quelques jours, vous aurez bien sûr quelques éléments à adapter) :

cd $HOME/temp
wget http://downloads.php.net/dsp/php-5.5.0alpha1.tar.bz2
tar xvf php-5.5.0alpha1.tar.bz2
cd php-5.5.0alpha1

Une fois ceci fait, nous allons pouvoir lancer le script configure – rendez-vous juste ci-dessous ;-)

Compiler et installer PHP depuis les sources que nous venons d’obtenir

La compilation et l’installation de PHP à partir des sources sous Linux se fait, de manière fort classique, en appelant sucessivement configure, make, et make install.

Configure

Maintenant, puisque nous avons obtenu les sources de la version de PHP qui nous intéresse, vous pouvez invoquer le script configure pour lister les options de configuration disponibles (il y en a un petit nombre, permettant pour la plupart d’activer ou non certaines extensions, les informations de débuggages, les différentes SAPI, …) :

$ ./configure --help
`configure' configures this package to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

[...]

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.

Voici un exemple de configure que j’ai tendance à utiliser pour obtenir une version de test de PHP, avec pas mal d’extensions activées (c’est avec cette commande de configuration que j’ai compilé les versions de test, depuis la branche master, utilisées pour ces articles) :

Attention : n’utilisez pas ceci sans réfléchir, pour un environnement de production !

./configure --prefix=$HOME/bin/php-5.5 \
    --with-apxs2=/usr/bin/apxs2 --disable-cgi --disable-ipv6 --with-openssl \
    --with-zlib --enable-bcmath --with-bz2 --enable-calendar --with-curl \
    --enable-ftp --with-gd --with-imap-ssl --enable-intl --enable-mbstring \
    --with-mcrypt --with-mhash --with-mysql=mysqlnd --with-mysqli=mysqlnd \
    --enable-pcntl --with-pdo-mysql=mysqlnd --with-pdo-pgsql --with-pgsql \
    --with-readline --enable-soap --enable-sockets --with-xmlrpc --with-xsl \
    --enable-zip --with-pear 

Notez que j’ai choisi d’installer les binaires créés vers une répertoire non-système, afin de ne pas risquer d’entrer en conflit avec la version de PHP, stable, installée depuis le gestionnaire de paquets de ma distribution – pour une version de test, c’est probablement plus sage ;-)

Si vous obtenez des erreurs lors de l’exécution de la commande de configuration, c’est généralement parce que certaines bibliothèques requises pour la compilation ne sont pas installées sur votre système (et doivent donc l’être, en version de développement).
En général, chercher le nom des bibliothèques concernées via votre outil préféré de gestion de packages et installer les paquets de développement correspondant devrait corriger ce type de problème.

A titre d’illustration et pour essayer de faciliter les choses à ceux d’entre-vous qui voudraient essayer, sous Ubuntu 12.04.1-server, la série de commandes suivantes devrait permettre d’installer le gros des paquets requis pour compiler PHP avec les options reproduites ci-dessus :

sudo apt-get update && apt-get dist-upgrade
sudo apt-get install apache2-mpm-prefork zip unzip make apache2 build-essential \
automake1.9 autoconf manpages-dev debian-keyring apache2-prefork-dev libxml2-dev \
libbz2-dev libcurl4-openssl-dev libpng12-dev libicu-dev libmcrypt-dev \
libxslt1-dev libltdl-dev

Si configure se termine correctement, vous devriez obtenir, à la fin de sa sortie, quelque chose de ce type :

Generating files
configure: creating ./config.status
creating main/internal_functions.c
creating main/internal_functions_cli.c
+--------------------------------------------------------------------+
| License:                                                           |
| This software is subject to the PHP License, available in this     |
| distribution in the file LICENSE.  By continuing this installation |
| process, you are bound by the terms of this license agreement.     |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point.                            |
+--------------------------------------------------------------------+

Thank you for using PHP.

config.status: creating php5.spec
config.status: creating main/build-defs.h
config.status: creating scripts/phpize
config.status: creating scripts/man1/phpize.1
config.status: creating scripts/php-config
config.status: creating scripts/man1/php-config.1
config.status: creating sapi/cli/php.1
config.status: creating sapi/fpm/php-fpm.conf
config.status: creating sapi/fpm/init.d.php-fpm
config.status: creating sapi/fpm/php-fpm.8
config.status: creating sapi/fpm/status.html
config.status: creating main/php_config.h
config.status: executing default commands

Une fois configure terminé avec succès, il est temps de passer à la compilation en elle-même.

Compilation

Passons maintenant à la compilation en elle-même, en invoquant la commande suivante :

make

En fonction des capacités de votre machine, cette étape peut durer un bon moment3

XKCD: The #1 programmer excuse for legitimately slacking off *Crédits : XKCD #303*

Si la compilation se termine correctement, vous devriez obtenir, en fin de sortie, quelque chose ressemblant à ceci :

Generating phar.php
Generating phar.phar
PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.
pharcommand.inc
directorygraphiterator.inc
clicommand.inc
invertedregexiterator.inc
directorytreeiterator.inc
phar.inc

Build complete.
Don't forget to run 'make test'.

Le moment est donc venu, comme suggéré, de lancer les tests.

Lancement des tests

Lancer les tests se fait, comme indiqué en sortie de make juste au-dessous, en exécutant la commande suivante (là aussi, selon la puissance de votre machine, ça peut durer un bon moment) :

make test

La sortie de cette commande commence par un rappel de la version de PHP utilisée – celle que nous venons juste de compiler :

=====================================================================
PHP         : /home/squale/temp/php-5.5.0alpha1/sapi/cli/php 
PHP_SAPI    : cli
PHP_VERSION : 5.5.0alpha1
ZEND_VERSION: 2.5.0-dev
PHP_OS      : Linux - Linux shark 3.2.0-31-generic #50-Ubuntu SMP Fri Sep 7 16:16:45 UTC 2012 x86_64
INI actual  : /home/squale/temp/php-5.5.0alpha1/tmp-php.ini
More .INIs  :  
CWD         : /home/squale/temp/php-5.5.0alpha1
Extra dirs  : 
VALGRIND    : Not used
=====================================================================

Vient ensuite l’exécution des tests en eux-même :

[...]
PASS Bug #26528 (HTML entities are not being decoded) [ext/xml/tests/bug26528.phpt] 
SKIP Bug #26614 (CDATA sections skipped on line count) [ext/xml/tests/bug26614.phpt] reason: expat test
PASS Bug #26614 (CDATA sections skipped on line count) [ext/xml/tests/bug26614_libxml.phpt]
[...]

Et, finalement, en fonction du nombre de tests en échec ou en succès, un résumé est affiché :

=====================================================================
TEST RESULT SUMMARY
---------------------------------------------------------------------
Exts skipped    :   27
Exts tested     :   51
---------------------------------------------------------------------

Number of tests : 12687             10275
Tests skipped   : 2412 ( 19.0%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :    2 (  0.0%) (  0.0%)
Expected fail   :   37 (  0.3%) (  0.4%)
Tests passed    : 10236 ( 80.7%) ( 99.6%)
---------------------------------------------------------------------
Time taken      :  525 seconds
=====================================================================

Avec une mise en évidence des éventuels tests en échec :

=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
PDO MySQL specific class constants [ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt]
show information about extension [sapi/cli/tests/006.phpt]
=====================================================================

Et, plus bas, vous avez la possibilité d’envoyer le rapport d’exécution des tests à la mailing-list QA de PHP.

Installation

Si vous jugez le résultat de l’exécution des tests satisfaisant – puisque vous installez une version de test, sur un environnement de développement ou une machine virtuelle, ignorer quelques échecs n’est probablement pas très génant –, vous pouvez passer à l’installation en elle-même, en lançant la commande suivante :

make install --ignore-errors

Deux points qui peuvent être à noter :

  • Si vous avez utilisé l’option --prefix de configure pour spécifier que les répertoires de PHP devaient être à un endroit où vous avez accès en écriture (sous votre $HOME, typiquement), cette commande n’a pas besoin d’être lancée en administrateur avec sudo,
  • Si cette commande n’est pas lancée en administrateur, l’installation du module PHP pour Apache 2 (option --with-apxs2 de configure) échouera, car elle essaye d’écrire vers /usr/lib/apache2/modules/ ; pour éviter cet échec (entre autres), make install accepte l’option --ignore-errors ; au besoin, nous déploierons manuellement ce module ultérieurement (l’idée étant de ne pas installer ce module, en version de développement non-stable, au niveau système, cet échec est une « bonne chose » !).

Configuration : php.ini

A la racine des sources de PHP, vous pouvez trouver deux exemples de fichier de configuration de PHP : php.ini-development et php.ini-production.

Puisque, ici, nous mettons en place un environnement de test, déployons le premier vers l’endroit attendu par la version de PHP que nous venons d’installer :

cp php.ini-development $HOME/bin/php-5.5/lib/php.ini

Par défaut, php.ini-development correspond assez bien à ce que l’on pourrait espérer sur un environnement de développement / test.
Quelques adaptations peuvent tout de même être nécessaires ; je pense en particulier à la directive date.timezone.

Vérification de l’installation de base

Maintenant que l’installation de PHP (version de développement, ou version alpha/beta/RC) est terminée, vérifions que celle-ci s’est bien passée.

Tout d’abord, en invoquant php en ligne de commande, en utilisant le chemin complet si vous avez installé vers un répertoire qui n’est pas dans le PATH de votre système :

$ $HOME/bin/php-5.5/bin/php --version
PHP 5.5.0alpha1 (cli) (built: Nov 17 2012 13:59:40) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.5.0-dev, Copyright (c) 1998-2012 Zend Technologies

Selon les sources que vous avez compilé, la sortie reproduite ci-dessus peut être différente, indiquant une version comme PHP 5.5.0-dev ou PHP 5.5.0alpha1.

Nous pouvons aussi vérifier que notre fichier php.ini est bien pris en compte :

$ $HOME/bin/php-5.5/bin/php --ini
Configuration File (php.ini) Path: /home/user/bin/php-5.5/lib
Loaded Configuration File:         /home/user/bin/php-5.5/lib/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

Ensuite, vous pouvez utiliser le serveur web intégré à PHP (depuis PHP 5.4), pour accéder à vos pages en HTTP ; par exemple, après avoir créé un fichier $HOME/www/phpinfo.php contenant ceci :

<?php 
phpinfo();
?>

Vous pouvez lancer le serveur comme suit (en adaptant l’adresse IP ou le nom de machine, et, éventuellement, le numéro de port) :

cd $HOME/www
$HOME/bin/php-5.5/bin/php -S 192.168.0.10:8888

Et accéder à la page qui vous intéresse en ouvrant un navigateur sur une URL de la forme http://localhost:8888/phpinfo.php donnera quelque chose de similaire à la capture d’écran que je reproduis ci-dessous (la capture d’écran reproduite ci-dessous correspond à la compilation d’une version des sources datant d’avant la publication de la première version alpha – ce qui explique le numéro de version différent de celui obtenu avec la sortie CLI un peu plus haut) :

Capture d'écran de phpinfo.php servi par le serveur intégré à PHP

En parallèle, dans la console depuis laquelle le serveur intégré à PHP a été lancé, vous devriez obtenir ce type de sortie :

PHP 5.5.0-dev Development Server started at Fri Sep 21 10:53:40 2012
Listening on http://192.168.0.10:8888
Document root is /home/user/www
Press Ctrl-C to quit.
[Fri Sep 21 10:53:46 2012] 192.168.0.6:40549 [200]: /phpinfo.php
[Fri Sep 21 10:53:46 2012] 192.168.0.6:40550 [404]: /favicon.ico - No such file or directory

Configuration Apache

Si vous avez choisi d’installer PHP vers un de vos répertoires personnels, et de ne pas effectuer une installation système, le module correspondant pour votre serveur web n’a probablement pas été déployé ; typiquement, souvenez-vous de l’échec obtenu plus haut lors du make install.

Plutôt que de déployer manuellement (en violant le système de gestion de paquets de votre distribution) une version instable du module PHP, une solution pratique lorsqu’il s’agit de tester est de lancer une instance de votre serveur web spécifique à cette version de test.

Avec Apache 2, que je prendrai ici comme exemple, en supposant que vous l’avez déjà installé de manière conforme à votre distribution, cela signifie :

  • Mettre en place un fichier de configuration d’Apache, indiquant notamment :
    • sur quel port il se lancera (le port 80 étant déjà pris par l’instance « normale », et ne vous étant pas accessible puisque vous n’êtes pas root),
    • quel répertoire servir,
    • et quels modules charger.
  • Lancer cette instance de test d’Apache
  • \o/

Commençons par créer un sous-répertoire qui nous servira pour stocker les fichiers liés à Apache, et y déployer le module que nous venons de compiler :

mkdir -p $HOME/bin/apache-php55/modules
cp libs/libphp5.so $HOME/bin/apache-php55/modules/

Créons un fichier de configuration Apache, qui chargera le module PHP, et servira les fichiers placés dans le répertoire www de notre utilisateur :

# /home/user/bin/apache-php55/apache.conf

LockFile /home/user/bin/apache-php55/accept.lock
PidFile /home/user/bin/apache-php55/pid.pid

User user
Group user

ErrorLog /home/user/bin/apache-php55/error.log
LogLevel warn

NameVirtualHost *:8888
Listen 8888

Include /etc/apache2/mods-available/mime.load
Include /etc/apache2/mods-available/mime.conf

# On veut que notre serveur Apache utilise le module PHP que nous venons de compiler
LoadModule php5_module        /home/user/bin/apache-php55/modules/libphp5.so
AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php-source .phps

<VirtualHost *:8888>
    ServerAdmin user@localhost

    DocumentRoot /home/user/www
    <Directory /home/user/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
    </Directory>

    CustomLog /home/user/bin/apache-php55/access.log combined
</VirtualHost>      

Et enfin, lançons Apache en utilisant ce fichier de configuration :

apache2 -f /home/user/bin/apache-php55/apache.conf

Et normalement, vous pouvez à nouveau interroger votre phpinfo.php créé plus haut… et servi, à présent, par Apache :

Capture d'écran de phpinfo.php servi par Apache

Arrêter Apache revient à killer le processus dont le PID est stocké dans le fichier pointé par la directive PidFile :

kill `cat /home/user/bin/apache-php55/pid.pid`


Arrivés ici, vous avez installé la version de développement de PHP sur un environnement de test, et elle est utilisable à la fois depuis la ligne de commandes, et depuis un serveur Web.


A vous, maintenant, d’expérimenter avec les nouveautés apportées par cette version !

Pour plus d’informations quant à ces nouveautés, je me permet de vous pointer vers quelques uns des articles que j’ai publié à propos de PHP 5.5 ces dernières semaines :

Et n’oubliez pas : PHP 5.5 n’est pas encore figée : des choses peuvent encore bouger !


Il s'agit ici d'installer une version de **développement** ou de **test**, pas vraiment / pas suffisamment testée *(si vous compilez une version alpha/beta/RC, c'est justement le but : tester que vos applications fonctionnent sur cette version)*, absolument non garantie, pouvant être très différente de l'éventuelle future version stable, éventuellement issue d'une extraction plus ou moins aléatoire du repository hébergeant les sources du langage ; l'idée d'installer une telle version sur un environnement de production ne devrait même pas vous traverser l'esprit...
Sous une distribution Linux comme Ubuntu, il vous faudra installer le paquet `git-core`.

`` Vous pouvez éventuellement jouer avec les options-jet-lde la commandemakepour paralléliser les processus de compilation, et ainsi gagner sur la durée totale de compilation. <br />Sur une machine avec un CPU quad-core,maje -j 8 -l 6` a tendance à bien réduire la durée de compilation, tout en permettant de continuer à utiliser le PC en même temps – sans le mettre à genoux, autrement dit.