MyWordPressUrlRewriteModule (Part 1) et comment héberger WordPress 2.3 sur IIS 7.0
Retrouvez la version 2 de cet article sur la MSDN à l’adresse http://msdn.microsoft.com/fr-fr/architecture/cc512087.aspx
L’ installation de WordPress sur un serveur IIS 7.0 est un peu différente de ce que l’ on pouvait faire avant !
En effet sous IIS6.0, nous avons le choix d’ exécuter notre PHP au travers des CGI, ISAPI ou alors, ce que j’ utilise actuellement en production et qui est le plus performant : le Fast-CGI pour IIS6.0 qui n’ est ni plus ni moins qu’ un autre filtre ISAPI utilisant de manière optimisée le processus "php-cgi.exe" ! (Pour les intéressés, une documentation pour l’ installation de PHP en Fast-CGI sur IIS6.0 ici)
De plus, afin de pouvoir profiter des permalink sous toutes ses formes et sans le "/index.php/" nous devions utiliser soit une astuce grâce aux erreurs 404 ou soit (et pour être plus propre) un module d’ URL Rewriting comme celui de Jon Tackabury que j’ utilise pour ce blog et disponible sur IIS.net. A ce sujet, vous retrouverez sur le site de WordPress plus d’ informations sur les permalink et IIS.
Windows Server 2008 étant sortie en RTM il y a maintenant dix jours, la migration de mes serveurs perso est imminente et j’ ai donc testé l’ hébergement d’ un site WordPress sous IIS7.0.
1/ Installation de PHP 5 sous IIS7.0
1.1 / Préparation de IIS pour Fast-CGI
Tout d’ abord, sous IIS 7.0 nous disposerons de deux modules natifs qui nous intéressons fortement nommé "CgiModule" et "FastCgiModule" qui vous faudra activer lors de l’ installation du rôle Web Server en sélectionnant entre autre "CGI" :
Les deux modules devraient être activés dans le fichier de configuration de IIS (dans %systemroot%\system32\inetsrv\config\applicationHost.config) sous la section globalModules (étant donné que ce sont des modules natifs ;)).
1 2 3 4 5 6 7 8 9 | <configuration> .... <system.webserver> .... <globalmodules> ...... <add image="%windir%\System32\inetsrv\cgi.dll" name="CgiModule" /> <add image="%windir%\System32\inetsrv\iisfcgi.dll" name="FastCgiModule" /> ...... |
La commande "appcmd list modules" devrait d’ ailleurs vous indiquer le bon chargement de ces deux modules :
1 2 3 4 5 6 | C:\Users\Administrator>%systemroot%\system32\inetsrv\appcmd list modules ..... MODULE "CgiModule" ( native, preCondition: ) MODULE "FastCgiModule" ( native, preCondition: ) ..... C:\Users\Administrator> |
1.2/ Installation de PHP et configuration Fast-CGI pour PHP
Il vous faudra ensuite configurer le module Fast-CGI avec PHP. Pour cela :
- Télécharger PHP 5 (en ZIP) que vous décompresserez dans c:\PHP\.
- Créer une copie du fichier php.ini-recommanded et le renommer en php.ini.
- Éditer ce fichier est redéfinir extension_dir = "C:\PHP\ext" qui nous servira un peu plus tard pour activer quelques extension de base de PHP. Pour plus’ informations sur l’ installation et la configuration de PHP je vous renvoi sur le site PHP.net ou sur cet article.
- Rajouter le bout de XML suivant dans votre fichier applicationHost.config dans la section system.webServer pour configurer le Fast-CGI au niveau de votre serveur :
1 2 3 4 5 6 7 8 | <configuration> .... <system.webserver> ...... <fastcgi> <application fullpath="C:\PHP\php-cgi.exe" /> </fastcgi> ....... |
Vous pouvez aussi réaliser cette manipulation par la simple commande :
1 | appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php\php-cgi.exe'] |
1.3/ Ajout du handler sur les extensions PHP
Une fois le module de Fast-CGI installé et configuré, nous allons ajouter un handler sur l’ extension PHP afin que le module Fast-CGI exécute nos pages PHP ! Vous pouvez ajouter ce handler directement au niveau de votre fichier applicationHost (au niveau "serveur") afin que tous vos sites IIS enfants héritent de cette configuration ou alors définir ce handler dans vos fichier web.config au niveau de votre "site", "application" ou même "répertoire virtuel".
Dans notre cas, nous ajouterons ce handler au niveau de notre serveur. Pour cela trois méthodes :
- Dans le fichier configuration applicationHost.config, ajouter la ligne ci-dessous sous la section system.webServer dans <location path=""> (qui regroupe la configuration de tous les sites IIS de notre serveur)
1 2 3 4 5 6 7 8 9 10 | <configuration> .... <location overridemode="Allow" path=""> .... <system.webserver> ...... <handlers accesspolicy="Read, Script"> ...... <add name="PHP-FastCGI" path="*.php" resourcetype="Either" scriptprocessor="c:\php\php-cgi.exe" modules="FastCgiModule" verb="*" /> ...... |
- Par AppCmd en tapant la commande :
1 | appcmd set config /section:system.webServer/handlers /+[name='PHP-FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\php\php-cgi.exe',resourceType='Either'] |
- Par la console d’ administration IIS, en sélectionnant notre serveur puis sur la page des features sélectionner "Handler Mapping" pour ajouter un nouveau handler et compléter le formulaire comme sur la capture ci-dessous :
Nous pouvons dès maintenant créer un fichier .PHP dans l’ un de vos sites IIS avec un simple <?php echo "Hello PHP" ?> pour s’ assurer que votre PHP est correctement exécuté par le serveur IIS.
2/ Installation de WordPress
2.1 / Les pré-requis : extensions PHP, MySql et phpMyAdmin
Tout d’ abord revenons dans le fichier de configuration de PHP (C:\PHP\php.ini dans notre cas) et dé-commenter les lignes suivantes afin d’ activer ces extensions pour le bon fonctionnement de WordPress et phpMyAdmin:
1 2 3 4 5 6 | extension=php_curl.dll extension=php_gd2.dll extension=php_mbstring.dll extension=php_mcrypt.dll extension=php_mysql.dll extension=php_mysqli.dll |
Nous allons ensuite installer un serveur MySql pour héberger notre base WordPress. Vous retrouverez l’ installeur de MySql pour Windows ici. Rien de bien compliqué, suivant, suivant, suivant 🙂
Ensuite, installer simplement un phpMyAdmin et créer la base WordPress ainsi qu’ un utilisateur :
- Télécharger phpMyAdmin
- Le décompresser dans un de nos sites IIS maintenant prêts pour accueillir du PHP
- Naviguer avec votre navigateur sur l’URL de cette application pour lancer la configuration (temporairement donner les droits CT dans votre dossier phpMyAdmin afin que l’ application PHP puisse créer le fichier de configuration config.inc.php)
- Créer ensuite un utilisateur (sur la page "Privilèges" > "Ajouter un utilisateur") en donnant un login et mot de passe et sélectionner "Créer une base portant son nom et donner à cet utilisateur tous les privilèges sur cette base" comme montré sur la capture ci-dessous :
2.2/ Installation de WordPress 2.3.3 sur IIS
Il ne nous reste plus qu’ a installer WordPress (à télécharger ici) avec La Célèbre Installation en 5 Minutes ! Mais attention la version actuelle de WordPress, version 2.3.3, ne fonctionnera pas sur un Windows/IIS au niveau de l’ installation dû a des erreurs d’ insertion SQL de ce type :
1 | WordPress database error Table 'wpdemo.wp_options' doesn't exist for query SELECT option_value FROM wp_options WHERE option_name = 'siteurl' made by is_blog_installed |
Pour résoudre ce problème remplacer le code du fichier wp-db.php du dossier wp-includes par le code publié sur Pastebin de wpforums – Fix for CGI Error – message n° 893007.
3/ Configuration des Permalink avec MyWordPressUrlRewriteModule
Maintenant notre WordPress fonctionnel sur notre serveur IIS7, intéressons-nous aux URL de notre blog, appelés aussi permalink (liens permanents).
Par défaut les liens sont sous la forme : http://www.monblog.com/?p=123 ce qui n’ est très explicite sur le contenu de cette page ! WordPress nous permet alors dans l ‘interface d’ administration sous "Options > Permaliens" de redéfinir la structure de ces liens pour avoir des URLs personnalisées du genre http://www.monblog.fr/index.php/2008/02/19/sample-post/ ce qui est déjà plus sexy !!
Mais encore une chose me dérange : le "/index.php/" dans l’ URL indispensable pour que WordPress puisse traiter la requête ! Comme je l’ évoquais en introduction, nous pouvons alors jouer avec les erreurs 404 ou utiliser des filtres ISAPI dans un pipeline en mode classique mais là n’ est pas notre but ! Nous allons en effet utiliser tout l’ intérêt de IIS 7.0, à savoir le mode intégré d’ un pool d’ application qui permet l’ exécution de modules natifs et managés dans notre pipeline IIS.
Nous allons donc ôter notre casquette d’IT et lancer notre Visual Studio pour créer notre module IIS 🙂
3.1/ Création du module IIS
Sous Visual Studio, Ouvrir > Site Web > Local IIS et sélectionner votre site où ce trouve votre blog WordPress. Ajouter alors une classe que l’ on nommera MyWordPressUrlRewriteModule.cs qui viendra se placer dans le dossier App_Code (créé automatiquement par VS).
Implémenter ensuite l’ interface IHttpModule et abonnez-vous à l’ événement BeginRequest de notre "context" (de type HttpApplication) dans la méthode Init. A l’ appel de cette événement nous allons simplement tester si le PhysicalPath de notre Request est un fichier ou dossier existant au quel cas nous ne ferons rien ! A l’ inverse, nous appellerons la méthode RewritePath en rajoutant ~/index.php devant notre RawUrl.
Le code de notre module sera donc très simple :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | using System; using System.IO; using System.Web; public class MyWordPressUrlRewriteModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); } void context_BeginRequest(object sender, EventArgs e) { HttpApplication context = (HttpApplication)sender; string physicalPath = context.Request.PhysicalPath; if (!(File.Exists(physicalPath) || Directory.Exists(physicalPath))) { context.Context.RewritePath("~/index.php" + context.Request.RawUrl); } } } |
La méthode RewritePath permet simplement de redéfinir un chemin d’ accès interne. Prenons ces quelques exemples :
Url démandée | Dossier ou fichier existant | Url interne |
/index.php | Oui | inchangée |
/wp-login.php | Oui | inchangée |
/wp-admin/xxx | Oui | inchangée |
/wp-content/xxx | Oui | inchangée |
/2008/02/19/sample-post | NON | /index.php/2008/0219/sample-post |
/a-propos | NON | /index.php/a-propos |
Comme nous le voyons, les fichiers wp-login.php, site d’ administration dans le répertoire wp-admin ou vos thèmes, plugins et médias de vos posts/pages dans le dossier wp-content ne seront pas affectés par notre module car ces derniers sont des fichiers physiquement existants par rapport avec l’URL demandée. Par contre les URLs du type http://www.monblog.fr/2008/02/19/sample-post/ n’ existe pas physiquement et donc seront "rewrités" par notre module sur l’URL http://www.monblog.fr/index.php/2008/02/19/sample-post/ qui sera ensuite attrapée et interprétée par WordPress.
3.2/ Activation du module dans le pipeline IIS
Une fois notre module développé nous allons l’ activer au niveau de notre site IIS hébergeant WordPress. Pour cela depuis la console d’ administration IIS, sur le site IIS de WordPress, entrer dans la feature "Modules" et ajouter depuis le panneau Action un module managé. IIS compilera dynamiquement votre site et détectera votre module que nous pourrons ensuite sélectionner comme "Type" comme le montre la capture ci-dessous :
Nous pouvons aussi ajouter manuellement dans le fichier web.config au niveau de la racine de votre site IIS (créé par Visual Studio lors de l’ ouverture du site) une balise add contenant la définition de notre module :
1 2 3 4 5 6 7 8 | <configuration> .... <system.webserver> .... <modules> ...... <add name="MyWpUrlRewrite" type="MyWordPressUrlRewriteModule" /> ...... |
3.3/ Configuration des permalinks dans WordPress
Maintenant notre module installé, il ne nous reste plus qu’ a personnaliser nos permalinks dans l’ interface d’ administration de WordPress dans "Options > Liens permanents" et personnaliser l’URL comme par exemple : /%year%/%monthnum%/%day%/%postname%/
Et le tour est joué, en naviguant sur une des pages de notre blog nous verrons alors des URLs du genre http://www.monblog.fr/2008/02/19/sample-post/ comme nous l’ avons spécifié dans la structure de nos "permaliens" !
3.4/ Module local ou partagé ?
N’ oubliez pas que nous n’ avons pas compilé notre module, il est simplement activé de manière locale sur notre site IIS WordPress. Mais il se peut (comme moi) que vous ayez plusieurs sites IIS hébergeant un site WordPress et par conséquent autant de sites IIS qui ont besoin de ce module.
Pour cela, plutôt que de recopier le code de votre module un peu partout, nous allons compiler la classe de notre module dans une assembly que l’ on placera dans la GAC.
Ouvrez donc Visual Studio et créer un projet de type "Bibliothèque de classes" dans lequel vous placerez la classe de notre module. Dans les propriétés de votre projet, dans l’ onglet "Signature", activer la signature de votre assembly :
Toujours dans la page des propriétés de votre projet, dans l’ onglet "Événements de génération", entrez la commande suivante afin de placer votre assembly signé dans la GAC afin de partager votre module sur votre serveur.
1 2 | call "%VS90COMNTOOLS%\vsvars32.bat" > NULL gacutil.Exe /if "$(TargetPath)" |
Mais attention à chaque compilation, votre module sera ré-installé dans la GAC et donc déployé surtout vos sites (attention donc si vous êtes sur un serveur en prod ;)).
Dans la console d’ administration IIS, en ajoutant un nouveau module vous trouverez dans les modules disponibles votre module avec un nom beaucoup long (le strongname de votre assembly) de type : MyWordPressUrlRewrite.MyWordPressUrlRewriteModule, MyWordPressUrlRewriteService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=54ce8ebb28415bb0 !
1 2 3 4 5 6 7 8 | <configuration> .... <system.webserver> .... <modules> ...... <add name="WpUrlRewrite" type="MyWordPressUrlRewrite.MyWordPressUrlRewriteModule, MyWordPressUrlRewriteService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=54ce8ebb28415bb0" /> ...... |
Conclusion
A partir de maintenant vous ajouterez donc votre module sur chacun de vos sites IIS utilisant WordPress depuis la console d’ administration IIS ou dans le fichier de configuration de votre site IIS (web.config) manuellement en XML. Mais attention ne l’ activez pas au niveau de votre serveur (applicationHost.config) car cela risquerait de perturber vos applications non WordPress.
Pour remédier à ce problème nous pourrions par exemple étendre le schéma de configuration IIS afin de rajouter une section pour savoir si le module doit rewriter ou non ! Cela permettrait de charger le module au niveau du serveur (applicationHost.config) et de l’ activer « plus bas » au niveau du site, application ou même répertoire dans un fichier web.config par une balise du type <MyWordPressUrlRewrite enabled="true" /> par exemple.
Étant donné que l’ on aura étendu notre schéma de configuration IIS nous pourrions même étendre notre console d’ administration IIS afin d’ y ajouter une simple feature permettant de configurer l’activation de notre rewriting dans notre fichier web.config de maniere graphique (ce qui fera fort plaisir aux ITs ^^)
La suite dans une partie 2 😉
Trackback: WordPress sous IIS7 | Here With Me
Greg-J
Hello à toi !!! Ton article m’a l’air très complet mais difficilement compréhensible pour qqn qui touche pas trop au dev comme moi…
Moi mon problème c’est que mes urls wordpress ne veulent pas se réécrire sauf, si je met le /index.php/ , mais si je le fais, les images (dans le header et la sidebar…) ne s’affichent pas ce qui très très problématique !!
Ta technique permettrait-elle d’afficher mes images ou alors vaudrait-il mieux que je fasse des réécriture via htaccess ?
Tu as testé ta méthode en ligne ???
Sebastien
Salut Greg-J !! En effet j’avais initialement prévu un package pour éviter aux non-devs d’avoir à ouvrir leur Visual Studio mais jamais eu le temps de concrétiser cela (note pour moi même : il n’est jamais trop tard !).
En effet, par défaut sur un serveur IIS (6 ou 7), il te faut mettre le /index.php/ pour que la requête soit bien traitée par WP.
Dans un 1er temps, il faudrait aussi que dans ton thème les liens commencent par un / afin de les faire pointer vers /wp-content/themes et non /index.php/wp-content/xxxx. Cela devrait résoudre les prbs avec tes images !
Comme IIS 7.0 te permet l’exécution de module en code managé (C#), cet article illustre un module permettant justement de gérer automatiquement le rewriting afin d’éviter d’avoir à écrire /index.php/ dans tes URLs (tout comme l’illustre mon site!).
Le module ajoutera de manière transparente le /index.php/ si la ressource n’existe pas comme expliqué dans le tableau de la partie 3.1.
Je te rassure cette technique a bien sûr était testée et marche parfaitement, mais attention celle-ci est uniquement valide dans le cas d’un hébergement de WP sur un serveur IIS 7.0 !!!
Sous IIS 6.0 ou 6.1 tu as un module ASAPI permettant de faire sensiblement la même chose. Tu trouveras ici : http://code.google.com/p/wp-url-rewriting-on-iis/downloads/list !
Les fichiers « htaccess » sont propre au serveur Web Apache ! Donc soit tu héberges ton WP sur du apache dans ce cas là mon article ne te seras d’aucune aide, il te faudra en effet jouer avec les htaccess, soit tu es sur du IIS est dans ces cas là il te faudra soit prendre un module ASAPI (IIS 6/7) ou soit si tu es sur un IIS 7.0 utiliser la technique illustrée dans cet article.
En espérant t’avoir éclairé..
Bien à toi,
Greg-J
En effet j’avais oublié les slashs ^^
Maintenant il me reste plus qu’à effacer le index.php, mais d’abord je dois me renseigner au près de mon hébergeur, très souvent indisponible !
Gaston
J’ai construit autour de WordPress, IIS7, PHP et MySQL un blog familial qui fonctionne bien en suivant les instructions précédentes et d’autres sur MSDN.Microsoft,
Je reste actuellement avec un problème qui semble lié aux permissions.
Ce problème survient lors de l’utilisation de NextGen, un plugin très populaire pour la gestion et l’affichage de photos. Le plugin permet de créer une galerie, et d’y importer des photos (puis de les afficher dans les articles).
Lors de la création, le plugin crée un répertoire avec le nom dela galerie, puis un sous répertoire pour les thumbs (vignettes). IUSER a les droits de lecture sur le répertoire, sur le sous-rpertoire, sur les vignettes, mais pas sur les photos originales placées dans le répertoire au nom de la galerie.
Je ne la comprends pas …
Gaston