PHP 5.3 : Configuration par répertoire basée sur des fichiers .ini

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

Les exemples correspondant à ce point se trouvent dans le répertoire "ini".

PHP 5.3 introduit, en mode CGI/FastCGI, de nouvelles possibilités au niveau de la configuration : il est maintenant possible de créer des fichiers de configuration par répertoire, à la façon des .htaccess de Apache, ou de définir dans le fichier php.ini des options en fonction de chemins ou de noms d'hôtes.

Sommaire :


Configuration par répertoire : .user.ini

La première nouveauté visible par les utilisateurs au niveau de la configuration est l'ajout, en PPHP 5.3, de la possibilité de définir des fichiers de configuration au sein des répertoires de votre application, un peu à la manière des fichiers .htaccess de Apache.

Principes des fichiers .user.ini

Par convention -- ou plutôt, par défaut, puisque c'est configurable -- ces fichiers sont nommés .user.ini.

Ils permettent de modifier des valeurs d'options de configuration de PHP ; les mêmes options de configuration que celles habituellement trouvées dans le fichier php.ini, au niveau de l'ensemble du serveur.

Les valeurs définies dans un fichier .user.ini s'appliquent pour les scripts définis dans le répertoire contenant ledit fichier, ainsi que dans ses sous-répertoires.
Attention tout de même : c'est le fichier .user.ini contenu dans le répertoire du script exécuté qui compte, et non ceux définis dans les répertoires contenus les scripts inclus par celui-ci !

A noter : pour des raisons évidente de -- notamment -- sécurité, il n'est pas possible de re-définir dans un fichier .user.ini la valeur de n'importe quelle directive de configuration !
Si on prend la liste des directives de configuration de php.ini, seules celles marquées en PHP_INI_PERDIR ou en PHP_INI_ALL peuvent être modifiées au sein d'un fichier .user.ini.
(Ca en fait tout de même un bon nombre ^^)

Juste pour la forme : le nom des fichiers de configuration par répertoire n'est pas figé : vous pouvez le modifier en changeant la valeur de la directive de configuration user_ini.filename dans votre fichier php.ini.
Une possiblité -- du moins sous Apache -- est d'utiliser un nom commençant par .ht, de manière à ce que ce fichier soit automatiquement masqué par Apache (c'est du moins généralement le cas), et ne soit pas téléchargeable par les utilisateurs de votre site.


Exemple de configuration par fichier .user.ini

A titre d'exemple, intéressons-nous aux directive de configuration variables_order et upload_max_filesize, valant par défaut dans le fichier php.ini de mon installation respectivement GPCS et 2M, comme vous pouvez le constater sur la capture d'écran ci-dessous :

ini-default-variables-1.png

Créons maintenant un fichier nommé .user.ini dans le répertoire où se trouve notre script appelant phpinfo.
Ce nouveau fichier modifiera la valeur des deux options que nous venons de voir :

variables_order = GPC
upload_max_filesize = "5M"

Et ré-affichons la page, ce qui nous donne l'affichage suivant :

ini-config-dir-variables-1.png

Dans le répertoire où se trouve notre script, les valeurs de ces deux directives ont été modifiées ; cela signifie par exemple que, lorsque nous exécutons un script se trouvant dans ce répertoire, nous pouvons uploader des fichiers deux fois et demie plus gros (5M au lieu de 2M) que lorsque nous exécutons un script localisé ailleurs sur notre serveur.

A titre de curiosité, si vous appelez la même page en exécutant PHP en tant que module Apache, et non en CGI, vous verrez que les valeurs définies dans le fichier .user.ini sont totalement ignorées : comme je le disais plus haut, cette nouvelle possibilité de configuration n'existe qu'en mode CGI !

Note : Les fichiers .user.ini sont mis en cache par le serveur (Cf directive de conf user_ini.cache_ttl) ; il peut donc être nécessaire de redémarrer votre serveur pour que les modifications apportées à un de ces fichiers soient prises en compte rapidement.


Exemple de directive ignorée dans le fichier .user.ini

Je disais un peu plus haut que, notamment pour raisons de sécurité, il n'était pas possible de re-configurer n'importe quelle directive via un fichier .user.ini.

A titre d'exemple, vous pouvez essayer de re-définir la directive upload_tmp_dir, qui est marquée comme configurable au niveau PHP_INI_SYSTEM :

upload_tmp_dir = "/home/php/temp/"

Cette modification de configuration ne lévera pas d'erreur... Mais elle ne sera pas prise en compte : vous n'avez pas la possibilité de modifier la valeur de cette directive dans un fichier .user.ini au niveau d'un répertoire.


php.ini : Sections PATH et HOST

La seconde nouveauté au niveau de la configuration de PHP, toujours en mode CGI, est l'ajout du support des sections PATH et HOST, utilisables dans le fichier php.ini.

Section PATH

Il est possible, à partir de PHP 5.3, de définir dans le fichier php.ini système des valeurs de directives de configuration qui ne seront appliquées que pour certains répertoires, un peu à la manière de ce que nous faisons plus haut avec les fichiers .user.ini...

... La différence étant que, cette fois :

  • La configuration est centralisée au niveau d'un seul fichier,
  • Et puisque nous travaillons dans le fichier php.ini système, accessible seulement par l'administrateur du serveur, nous pouvons modifier des options de configuration qu'il ne nous était pas possible de modifier dans les fichiers .user.ini, pour raisons de sécurité.

Une section PATH se défini en prenant en paramètre le chemin (au sens "système de fichiers") sur lequel les directives qu'elle défini doivent s'appliquer.

Par exemple, définissons deux sections PATH dans notre fichier php.ini, comme suit :

[PATH=/home/php/php53/ini/exemple-2/a]
variables_order = GPC
upload_max_filesize = "5M"
upload_tmp_dir = "/home/php/temp/"

[PATH=/home/php/php53/ini/exemple-2/b]
variables_order = GPC
upload_max_filesize = "7M"

Pour les scripts PHP qui seront exécutés depuis le répertoire << a >>, nous pourrons par exemple uploader des fichiers allant jusqu'à 5 Mo :

ini-config-section-PATH-a-2.png

Et on constate que, cette fois-ci, la modification de valeur de la directive upload_tmp_dir a bien été prise en compte : dans le fichier php.ini système, nous avons le droit de la modifier, contrairement à ce que nous avions remarqué plus haut pour les fichiers .user.ini.

Dans le second répertoire, << b >>, la limitation de taille en upload est cette fois-ci configurée à 7 Mo :

ini-config-section-PATH-b-1.png

A chaque fois, j'ai pris des directives de configuration << géographiquement proches >> dans la sortie de phpinfo, pour me faciliter les choses...
... Bien entendu, vous pouvez aussi essayer avec d'autres options ^^


Section HOST

Cela intéressera surtout ceux d'entre-vous qui hébergent plusieurs sites sur un seul serveur : depuis PHP 5.3, en mode CGI, il est possible de définir des directives de configuration en fonction de l'hôte -- et donc du site -- auquel l'utilisateur accède.

Par exemple, on peut ajouter au sein du fichier php.ini système une section telle que celle-ci :

[HOST=172.16.133.128:8080]
variables_order = GPC
upload_max_filesize = "5M"
upload_tmp_dir = "/home/php/temp/"

Une section HOST prend en paramètre le nom d'hôte pour lequel elle doit être considérée.
Vous noterez que ici, un numéro de port est inclu ; en effet, le numéro de port est considéré comme faisant parti du nom d'hôte, comme on peut le constater ci-dessous :

ini-cgi-_server-host.png

Accessoirement, si vous obtenez une section "PHP Variables" vide suite à l'appel de phpinfo, vérifiez que la directive variables_order prise en compte pour l'exécution de votre script inclut bien les variables serveur -- la lettre S, donc.

Mais, au fait, avec ces nombreuses nouvelles possibilités de configuration, où va être définie la directive variables_order ?

  • Dans le fichier php.ini système ?
    • Eventuellement, re-définie, au sein d'une section PATH ou HOST ?
  • Ou est-ce qu'elle sera re-définie dans le .user.ini de votre répertoire ?
  • Ou même dans un fichier .user.ini situé dans l'un des répertoires père de celui où se trouve votre script ?

Vous l'aurez compris, ces nouvelles fonctionnalités ne sont pas sans présenter un risque : celui d'avoir du mal à vous y retrouver au sein de vos fichiers de configuration !
A vous donc de ne pas en abuser, et de les utiliser à bon escient %)

Pour ce qui est de la documentation officielle, vous pouvez vous référer à List of php.ini sections.


PHP en CGI/FastCGI

Comme je le disais en introduction, ces nouvelles possibilités ne sont proposées qu'en mode CGI et/ou FastCGI. Cela signifie notamment qu'il n'est pas possible d'en bénéficier si PHP tourne, sur votre hébergement, en mode Apache -- ce qui a souvent tendance à être le cas, du moins en dehors des contextes de type hébergements mutualisés.

Compilation de PHP en CGI

En tout premier lieu, pour pouvoir utiliser PHP en mode CGI, il faut que cela ait été rendu possible au moment de sa compilation.
Je ne rentrerai pas une seconde fois dans les détails de la compilation de PHP, et vous laisse vous référer au premier artice de cette série : Configuration de la compilation.

Cela implique notamment que la compilation a dû se faire sans inclure l'option --disable-cgi.

Typiquement, la commande de configuration au moment de la compilation de PHP aura ressemblé à quelque chose de ce type :

./configure --prefix=/usr/ --with-config-file-path=/etc/php/ --disable-ipv6 --with-curl --enable-ftp --with-gd --enable-intl --enable-mbstring --with-mcrypt --with-mhash --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-soap --with-pear --with-xsl --with-zlib --with-openssl

Une fois les étapes de compilation et d'installation terminées, vous devriez avec un exécutable nommé php-cgi déployé dans /usr/bin/ :

# ll /usr/bin/ | grep php
-rwxr-xr-x 1 root   root    21987756 2008-11-02 00:53 php
-rwxr-xr-x 1 root   root    22036315 2008-11-02 00:53 php-cgi
-rwxr-xr-x 1 root   root        2446 2008-11-02 00:53 php-config
-rwxr-xr-x 1 root   root        4174 2008-11-02 00:53 phpize

C'est cet exécutable qui devra être appelé par votre serveur Web pour exécuter les scripts PHP.


PHP en CGI : Configuration Apache

Puisque les fonctionnalités vue plus haut ne fonctionnent qu'en mode CGI, nous allons devoir reconfigurer Apache, qui utilisait d'habitude PHP en tant que module.

Les modifications suivantes sont à apporter au niveau du fichier de configuration correspondant à notre site :

  • Activer l'option ExecCGI
  • Activer le gestionnaire cgi-script pour les fichiers PHP

N'hésitez pas à consulter la documentation d'Apache pour les détails...

Sur l'installation que j'utilise, sous Ubuntu, il faut modifier le fichier /etc/apache2/sites-enabled/000-default, pour le faire ressembler à ceci :

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /home/php/php53/
    <Directory /home/php/php53/>
        Options Indexes FollowSymLinks MultiViews +ExecCGI
        AllowOverride All
        Order allow,deny
        allow from all
        AddHandler cgi-script php
    </Directory>
    ErrorLog /var/log/apache2/error.log
    LogLevel warn
    CustomLog /var/log/apache2/access.log combined
    ServerSignature On
</VirtualHost>

Ensuite, il faut rendre nos fichiers PHP exécutables par Apache... et il ne reste plus qu'à redémarrer le serveur pour que le changement de configuration soit pris en compte.

Un appel à phpinfo() devrait alors ressembler à ceci :

ini-php-cgi.png

Notez la ligne Server API, valant maintenant CGI/FastCGI, et non plus Apache 2.0 Handler comme lorsque PHP fonctionnait en module Apache.


PHP en CGI : Configuration lighttpd

Une solution alternative, que j'aurais même tendance à préférer, puisqu'il ne s'agit de déployer un PHP en mode CGI que pour tester quelques exemples, serait de ne rien changer à la configuration Apache existante, qui fonctionne très bien, et d'installer un autre serveur Web, qui, lui, soit configuré pour écouter sur un autre port, et travailler avec PHP en mode CGI :

  • Soit une seconde instance d'Apache,
  • Soit un autre serveur Web -- LightTPD, par exemple.

C'est cette seconde solution que nous allons mettre en oeuvre ici.
Pour cela, deux étapes :

  • Installation de lighttpd
  • Configuration

Installation de lighttpd

Fondamentalement, du moins sous Ubuntu le principe est le plus basique qui soit :

apt-get install lighttpd

Et voilà, c'est installé ^^

Configuration de lighttpd

Pour ce qui est de la configuration, puisqu'Apache écoute déjà sur port 80, nous configurerons lighttp pour qu'il écoute sur port 8080.
Pour cela, modifier le fichier /etc/lighttpd/lighttpd.conf, et modifier la ligne server.port :

## bind to port (default: 80)
server.port               = 8080

Il faut ensuite activer le module FastCGI, en créant le lien symbolique qui va bien :

ln -s /etc/lighttpd/conf-available/10-fastcgi.conf /etc/lighttpd/conf-enabled/10-fastcgi.conf

La configuration par défaut devrait permettre de faire tourner PHP convenablement pour nos tests ; vérifiez tout de même le chemin vers l'exécutable php-cgi dans le fichier que nous venons de lier.

Il ne reste plus qu'à lancer le démon lighttpd :

# /etc/init.d/lighttpd start
 * Starting web server lighttpd

Nos scripts de tests devraient maintenant être accessibles sur port 8080, en utilisant PHP en mode CGI, sans avoir altéré notre configuration Apache et son module PHP.
Typiquement, un appel à phpinfo() devrait donner quelque chose de ce genre :

ini-lighttpd-1.png