Depuis quelques années, PHP prend de plus en plus d’importance en développement Web. Comment faire tourner PHP sur une plateforme Microsoft ? Comment l’installer ? Quels sont les petits (et gros) pièges ? Il est évidemment impossible d’être exhaustif en quelques pages, mais cet article essaie de balayer les fondamentaux.
Quelle version de PHP installer ?
PHP se compose aujourd’hui de plusieurs grandes briques :
- Le runtime
- Les extensions
- Les frameworks divers
Le runtime est le binaire chargé d’intercepter vos requêtes et de les traiter. La version majoritaire actuelle est PHP 5.2, mais PHP 5.3 devient rapidement la norme, et il existe des différences non négligeables entre les deux environnements, particulièrement sur une plateforme Microsoft.
En effet, les binaires PHP est composés de plusieurs sources (en gros, le runtime lui-même et les extensions), et pour les unifier il faut un compilateur adapté. Le premier compilateur utilisé fréquemment sous windows pour produire un binaire PHP est Visual C 6, c’est-à-dire un produit qui a plus de 10 ans. Même si la qualité de ce compilateur n’est pas à prouver, force est de constater qu’il a vieilli : nous en sommes aujourd’hui à la version 9, qui apporte un certain nombre de nouveautés intéressantes pout PHP :
- Compilation 64 bits
- Optimisations de performance
- Meilleure sécurité
Pour n’en citer que quelques-unes. Comme nous sommes en période de transition, vous trouverez PHP 5.3 en plusieurs versions : des versions VC6, pour assurer la compatibilité avec des modules non encore disponibles sous VC9, et VC9.
Au-delà du compilateur, il existe également deux versions de PHP : l’une est thread-safe, et l’autre non. En d’autres termes, la version thread-safe a été conçue pour être réentrante, en protégeant certaines sections de code pour garantir qu’une exécution simultanée est impossible et que vous ne pouvez pas corrompre les données d’un utilisateur lorsqu’un autre utilisateur consulte votre site Web. Intéressant ? Oui, mais le prix à payer en performance n’est pas négligeable. Utiliser la version non-thread-safe peut sembler un peu inquiétant mais rassurez-vous, l’isolation des processus est assurée à un autre niveau : dans IIS.
Comment IIS exécute vos applications PHP
IIS a la possibilité d’exécuter PHP dans trois modes, et il est important de bien les comprendre :
PHP en processus CGI
Dans ce mode d’exécution, IIS lance un nouvel exécutable PHP pour chaque nouvelle requête. Ce type de fonctionnement est extrêmement lent, et est très rarement utilisé en production. Si votre serveur reçoit une très faible charge, c’est cependant un mode d’exécution offrant une très grande stabilité.
PHP en mode ISAPI
Cette approche a longtemps été la plus performante sous IIS (et Apache, par le biais de modphp). La raison de cette performance est aussi la cause de sa fragilité : toutes les requêtes PHP sont en effet envoyées dans le même binaire PHP, et ce binaire est directement chargé dans IIS. Si l’une de vos applications se comporte mal et fait planter le binaire PHP, l’exécutable dans lequel il vit va subir le même sort, et votre serveur web entier peut tomber. Cette approche impose d’utiliser la version thread safe de PHP, et peut dans certains cas apporter un peu plus de performance que la suivante, mais au détriment de la stabilité.
PHP en mode FastCGI
Le mode fastCGI est un raffinement de CGI : comme dans CGI, IIS passe le contrôle à un autre exécutable lorsqu’une requête PHP lui parvient. La différence est dans la gestion de l’autre exécutable : dans CGI, il est simplement détruit et un autre sera relancé à la requête suivante. Dans le cas de fastCGI, l’exécutable reste chargé en mémoire et servira plus tard à traiter une autre requête. Pour les curieux, la communication entre l’exécutable et IIS est assurée par des canaux nommés en mémoire (on peut aussi utiliser des canaux TCP mais la performance est moindre). Ce mode de fonctionnement permet de fournir des performances identiques à celles de la version ISAPI, en consommant un peu plus de mémoire mais avec une stabilité très supérieure. Vous pouvez dans ce mode utiliser les versions non thread safe de PHP.
En conclusion, les configurations que vous devez privilégier sont dans cet ordre :
Version 5.3 de PHP, pour VC9, en mode non thread safe, et avec IIS en mode FastCGI.
Version 5.2 de PHP, pour VC6, en mode non thread safe, IIS en mode FastCGI
Attention : lorsque vous fonctionnez en mode fastcgi, le processus php-cgi.exe reste en mémoire entre deux appels au serveur Web. Si vous êtes en développement et que vous modifiez le runtime PHP (ajout de nouvelles extensions par exemples), il est important de redémarrer IIS pour forcer l’arrêt et le redémarrage de tous les processus PHP qui pourraient vivre en mémoire. Pour relancer IIS, je vous suggère d’ouvrir un command prompt en mode administrateur et d’y exécuter la commande iisreset chaque fois que vous en avez besoin.
Comment procéder à l’installation de PHP sous IIS
Les pré-requis
Installer PHP sous IIS est relativement simple, et demande simplement de vérifier que quelque pré-requis sont bien respectés. Microsoft met à disposition un utilitaire d’installation que je vous recommande, le Web Platform Installer (téléchargeable sur http://www.microsoft.com/web). Cet outil permet d’automatiser l’installation de toutes les dépendances de PHP, ainsi que de PHP lui-même.
Cependant, la version de PHP actuellement disponible sur WebPI n’est pas la plus récente (il s’agit de la version 5.2), et le chemin d’installation par défaut n’est pas celui que vous voudrez forcément utiliser (les binaires sont installés dans Program Files, ce qui peut être gênant notamment si vous désirez apporter des modifications à PHP.INI). Il faut également noter que l’installation contenue dans WebPI déploie automatiquement un grand nombre d’extensions alors que vous voudrez probablement minimiser celles que vous mettez à disposition de vos applications PHP.
La solution que je vous recommande est de passer par WebPI pour les prérequis et de passer par le site http://windows.php.net pour l’installation de PHP en lui-même.
Pré-requis pour installer PHP sur une machine de production :
IIS+document par défaut+contenu statique+module de réécriture d’URL
CGI - FastCGI (et son hotfix pour IIS 7)
Pour installer ces pré-requis, vous pouvez utiliser ce lien :
http://www.microsoft.com/web/gallery/install.aspx?appid= IIS60;IIS51;StaticContent;defaultdocument;directorybrowse;httperrors;httplogging;loggingtools;requestmonitor;requestfiltering;statuscontentcompression;iismanagementconsole;cgi;FastCGIIIS6;fastcgibackport
Installation du runtime PHP
Pour installer PHP, je vous conseille de réfléchir un peu à votre environnement de production avant de vous lancer dans l’aventure. Les questions les plus importantes sont :
- Quelles sont les permissions dont votre application a besoin sur le disque ?
- Quelles sont les extensions dont vous avez besoin pour fonctionner ?
- Quelle version de PHP comptez-vous utiliser ?
- Le serveur est-il dédié à un site PHP ou partagé par plusieurs sites ?
Si votre serveur doit héberger plusieurs applications PHP, je vous suggère de toutes les faire tourner avec la même version de PHP : c’est un peu plus de travail en recette mais beaucoup moins de risques en maintenance.
Une fois les décisions prises, passons à l’installation de PHP. La méthode que je vous recommande est de passer par l’installeur disponible sur http://windows.php.net. Ne prenez pas le zip à moins de savoir exactement ce que vous faites, car il installe un grand nombre d’extensions et ne paramètre pas FastCGI pour IIS.
L’installeur va vous guider pas à pas dans le processus d’installation et gérer pour vous trois aspects importants :
- 1/ Renseigner les variables d’environnement permettant à PHP de savoir où trouver PHP.INI
- 2/ limiter le nombre d’extensions et les configurer dans PHP.INI
- 3/ Configurer FastCGI pour IIS
La checklist est donc la suivante :
a/ Choisissez votre version de PHP (je recommande chaudement les versions Non Thread Safe)
b/ Choisissez le chemin d’installation
Si vous comptez utiliser plus d’une version de PHP, je vous suggère de créer l’arborescence suivante :
Vous installerez la version principale de PHP dans \PHP\Default, en vous réservant la possibilité d’installer des binaires spécifiques dans un répertoire correspondant au nom du site que vous souhaitez personnaliser.
c/ Choisissez les modules que vous voulez installer. Moins vous en aurez, mieux vous maitriserez la configuration de votre site. A noter que l’installeur proposé sur http://windows.php.net permet de modifier la liste des extensions installées par simple ré-exécution du MSI.
d/ Demandez l’installation de PHP pour FastCGI. Vous pourrez par la suite faire pointer d’autres sites vers d’autres versions de PHP, mais il est nécessaire de faire une première fois un certain nombre de tâches de configuration dans IIS, et c’est ce que permet cette option.
Paramétrage de PHP pour une bonne exécution sous Windows.
Ce paramétrage doit se faire à deux niveaux : d’une part dans IIS, pour que les requêtes soient correctement passées et que IIS puisse gérer quelques aspects spécifiques à PHP, et ensuite dans votre php.ini, qui doit lui aussi être adapté pour un bon fonctionnement sous IIS.
Le paramétrage d’IIS et FastCGI
Pour que PHP se comporte correctement, vous devez définir ou vérifier un certain nombre de paramètres définis dans IIS, et plus spécifiquement dans les paramètres fastCGI :

Vous voyez dans la copie d’écran ci-dessus quelques-uns des paramètres définis pour l’exécution de PHP via FastCGI. Les paramètres importants sont les suivants :
Nombre max d’instances : c’est le nombre de processus php-cgi.exe que FastCGI est autorisé à exécuter simultanément. Vous pouvez mettre 0 pour laisser FastCGI optimiser ce paramètre en fonction de votre configuration
Demandes d’instance max : ce paramètre définit le nombre de requêtes acceptés par votre processus avant recyclage. Attention, PHP dispose de son propre système de recyclage de processus, et vous devez vous assurer que celui-ci ne prendra pas la main au mauvais moment. Pour ce faire, il vous faut modifier une variable d’environnement définie au lancement du processus php-cgi.exe par FastCGI :

Vous voyez ici l’ensemble des paramètres vous permettant d’influer sur le comportement de php :
Analyser les modifications du fichier permet de définir le paramètre MonitorFileChanges, il sert à redémarrer les instances de php-cgi.exe en cas de modification du fichier php.ini (ce qui vous évitera de faire iisreset à chaque mise à jour).
Le nombre maximal de demandes d’instances doit être supérieur à PHP_FCGI_MAX_REQUESTS : ce dernier paramètre est celui que PHP utilise pour déterminer qu’il doit redémarrer, et vous ne voulez pas que PHP redémarre sans en avoir reçu l’ordre depuis IIS.
L’autre variable d’environnement est très importante : PHPRC est en effet l’une des techniques que le runtime PHP utilise pour déterminer le chemin d’accès au fichier PHP.INI qu’il doit prendre en compte. Si vous désirez déployer en production plusieurs versions de PHP, c’est ce paramètre qui vous permettra de faire pointer chaque runtime PHP vers son PHP.INI.
Le paramétrage de php.ini
Ce fichier comporte le paramétrage fin de PHP, ainsi que la liste des extensions chargées au démarrage de PHP. Voici la liste des points à vérifier sur votre installation :
fastcgi.impersonate = 1
Ce paramètre permet à PHP de fonctionner sous le compte utilisé par IIS. Pour les accès anonymes sous IIS7 et IIS7.5 il s’agit du compte IUSR, et c’est à lui que vous devrez donner les permissions adéquates (par exemple pour utiliser la sécurité intégrée dans sql server, ou accéder à des fichiers)
cgi.fix_pathinfo=1
Il s’agit d’une correction mineure des variables d’environnement.
cgi.force_redirect = 0
Pas ou peu de documentation sur ce paramètre, il est apparemment utilisé pour Apache pour mitiger un risque de sécurité
extension_dir = "…"
C’est l’emplacement où résident les extensions que vous désirez monter dans le runtime PHP.
Quel est le compte qui fait tourner votre runtime PHP ?
Attention, cette section est capitale pour comprendre la sécurité et les droits d’accès de votre application, et les bonnes pratiques sont bienvenues en ce domaine, particulièrement si vous hébergez plusieurs applications Web sur un environnement de production. Afin de simplifier un peu la discussion je vais me limiter aux versions récentes de Windows, les comptes de sécurité par défaut ayant pas mal évolué dans les dernières versions d’IIS.
L’identité de votre processus est déterminée par un ensemble d’étapes. Supposons qu’une bête requête arrive sur votre serveur, et voyons comment IIS va la traiter et déterminer qui l’exécute.
1/ Le serveur accepte les accès anonymes
Dans ce cas, IIS va utiliser l’identité associée à l’utilisateur anonyme pour déterminer s’il a le droit de poursuivre son chemin jusqu’à la page (ou image) demandée. Le premier compte à connaître est celui qu’IIS tente d’attribuer à PHP-CGI.exe. Dans IIS, les applications Web sont exécutées dans des pools d’applications. Chaque pool d’applications a un paramètre important pour PHP : son identité. Les valeurs courantes de cette identité sont :
LocalService, NetworkService, ou LocalSystem
Ce sont les comptes de service pré-définis habituels. Il existe cependant un autre type d’identité prédéfinie :
ApplicationPoolIdentity
Il s’agit d’un compte nommé IIS APPPOOL\NomDuPool qui est créé et maintenu dynamiquement par le système. Choisir ApplicationPoolIdentity (c’est la valeur par défaut sous IIS 7.5) permet d’avoir automatiquement un compte de service distinct par pool d’application, et donc une meilleure isolation entre les différents sites web associés à ces pools.
Tout compte de votre choix
Vous pouvez bien évidemment attribuer un compte de votre choix.
Est-ce que ce compte est celui qui fait tourner mon processus PHP ?
Oui et non : en mode anonyme oui, en mode authentifié c’est une question de paramétrage
2/ Le serveur refuse un accès anonyme.
Dans ce cas, IIS et le navigateur vont négocier pour déterminer votre identité. Si cette identité est un compte windows, PHP va prendre une décision en fonction du paramètre fastcgi.impersonate présent dans PHP.INI. Si cette valeur est à 1, l’identité qui exécute votre requête est celle de l’utilisateur. Si la valeur est nulle, c’est toujours le compte anonyme qui exécute php-cgi.exe.
Attention, il est également possible de changer cette valeur dans les paramètres du site, auquel cas le compte défini pour le site sera utilisé en lieu et place du compte défini par le pool d’applications.
Quelques erreurs fréquentes
Attention, les pièges sont nombreux sur les extensions, en voici quelques-uns :
Mauvaise version de PHP.INI : veillez toujours à contrôler que PHP utilise bien le PHP.INI de votre choix, si ce n’est pas le cas vérifiez la variable d’environnement PHPRC. Le symptôme : vous modifiez PHP.INI et vos modifications ne sont pas prises en compte.
Oubli du redémarrage d’IIS : si vous n’avez pas correctement configuré IIS pour qu’il redémarre automatiquement PHP lorsque vous modifiez le fichier php.ini (par défaut il n’est pas surveillé), les modifications de php.ini ne sont prises en compte qu’au lancement d’un nouveau php-cgi.exe. Symptôme : vous faites des modifications et vous testez, le comportement est variable (vous tombez une fois sur deux sur le php-cgi.exe qui a pris en compte vos modifications, et une fois sur deux sur le précédent).
Mauvaise version des extensions : si vous ne prenez pas la version de l’extension correspondant à votre binaire (version thread safe sur un binaire php non thread safe par exemple), son chargement ou son initialisation échouent. Symptômes : variés, depuis la page blanche jusqu’à un message d’erreur abscons.
open_basedir = "…"
Cette directive permet de restreindre les droits d’accès fichier du runtime PHP aux répertoires spécifiés (séparateur : point-virgule). Veillez à terminer le nom de chaque répertoire par un antislash.
Pour vérifier (et paramétrer) simplement les aspects PHP.ini, n’oubliez pas PHP Manager.