Il peut être intéressant de séparer une application web en plusieurs sous-applications pour plus de clarté : notamment dans le cas d’un site avec un back-office. Cela peut aussi être très utile dans le cas où certaines rubriques d’un site nécessitent beaucoup de fichiers (controlleurs, vues, etc…). Voici une méthode qui permet de le faire assez simplement et de manière efficace, quelle que soit la version de CodeIgniter.
Le problème
La documentation de CodeIgniter propose de faire cette séparation en créant autant de sous-dossiers qu’il y a d’applications dans le répertoire « application » et d’y dupliquer tous les répertoires nécessaires. Le problème avec cette approche vient du fait qu’il y a un risque de duplication de code puisque chaque application est totalement indépendente. Par exemple il faudra plusieurs fichiers de configuration, plusieurs fichiers de routes… Pire encore : si vous souhaitez partager des librairies, helpers, models, etc… ça ne sera pas possible et il faudra également les dupliquer.
Sur ce dernier point, depuis la version 2 de CodeIgniter ce n’est plus tout à fait exact : on peut utiliser le dossier « third_party » pour y partager configurations, helpers, models et librairies – mais il n’y a toujours pas de séparation des applications et l’on ne peut pas interagir avec le router.
Une solution
En effet il n’y a pas une seule et unique solution au problème mais je vous une présente une que je trouve assez astucieuse, relativement simple à mettre en place et qui ne nécessite aucune librairie ni overload de classes. Elle se résume en deux mots : liens symboliques.
Mise en œuvre
Pour cette article nous partirons du postulat que nous voulons créer un site web en local (pour le développer bien sûr^^) et séparant le front-office (ce que voit le visiteur) du back-office (ce qu’utilise le(s) gestionnaire(s) du site).
Pour commencer il faut choisir une stratégie de différenciation des applications : adresse IP, sous-domaine, URI, session… ou, vraisemblablement, une combinaison de ces possibilités. Pour l’example nous utiliserons un sous-domaine « admin » pour le back-office, le front-office étant sur « www ».
Configuration hosts
En développement local j’utilise toujours des hôtes virtuels et comme je travaille sur un Mac utilisant MAMP, j’explicite les réglages pour cette plateforme – mais c’est à peu de choses près la même chose sous Windows et Linux. Bref :
On édite le fichier /private/etc/hosts en y ajoutant à la fin deux lignes :
127.0.0.1 www.montest.local 127.0.0.1 admin.montest.local
Sous Lion faites bien attention à ce qu’il y ait une ligne vierge à la fin du fichier, comme je l’explique dans cet article.
Configuration Apache
Les serveurs de MAMP doivent être arrêtés et l’on édite le fichier /Applications/MAMP/conf/apache/httpd.conf en y ajoutant les deux serveurs virtuels correspondants à ce que nous avons ajouté dans le fichier hosts :
<VirtualHost *:80> DocumentRoot /Applications/MAMP/htdocs/montest/www/ ServerName www.montest.local </VirtualHost> <VirtualHost *:80> DocumentRoot /Applications/MAMP/htdocs/montest/www/ ServerName admin.montest.local </VirtualHost>
Vous noterez que le document root est « www » et non la racine du site, ceci pour des raisons de sécurité : le serveur apache ne permettra que d’accéder aux fichiers nécessaires à l’application : le bootstrap (index.php) et les ressources (javascript, images, css).
Arborescence du projet CodeIgniter
Nous allons modifier l’arborescence de base de CodeIgniter pour prendre en compte la séparation d’applications et le déplacement des fichiers d’application et du framework :
Les modifs sont les suivantes :
- Le répertoire « application » à été renommé « applications »
- Les répertoires « bo » et « fo » ont été créés
- Le contenu originel du répertoire « application » a été déplacé dans « bo »
- Un répertoire « www » a été créé au même niveau que « applications » et index.php y a été déplacé
Dans le répertoire « fo » nous rajouterons les répertoires « controllers » et « views » et c’est là que la séparation aura effectivement lieu : le front-office aura ses propres controlleurs et vues. Tout le reste proviendra du répertoire « bo ».
L’astuce pour que ça marche
Comment le framework va-t’il trouver les modèles, librairies, etc… dans la partie front alors qu’il n’y sont pas ? Tout simplement en utilisant des liens symboliques de Linux. Pour les créer, un petit tour dans le Terminal, en se plaçant dans le répertoire « fo » il n’y plus qu’a tapper les lignes suivantes (en validant ligne par ligne) :
ln -s ../bo/cache cache ln -s ../bo/config config ln -s ../bo/core core ln -s ../bo/errors errors ln -s ../bo/helpers helpers ln -s ../bo/hooks hooks ln -s ../bo/language language ln -s ../bo/librairies librairies ln -s ../bo/logs logs ln -s ../bo/models models ln -s ../bo/third_party third_party
Et le tour est joué ! Ou presque…
Configurer index.php
Comme nous avons modifié l’arborescence du framework il faut lui indiquer où trouver ses fichiers, mais aussi lui indiquer quelle application utiliser. Nous modifions donc /www/index.php :
[...] $system_path = '../system'; // on a sorti le framework du webroot (sécurité) [...] // changement application en fonction du sous-domaine // a modifier en fonction de la stratégie de différenciation choisie if( preg_match('/admin\.*/', $_SERVER['SERVER_NAME']) ) { $app_folder = '/bo'; } else { $app_folder = '/fo'; } $application_folder = '../applications' . $app_folder; // les applications sont également en dehors du webroot (sécurité)
A noter qu’il s’agit là d’une partie du fichier index.php de la version 2.0.3 du framework – le reste n’étant pas intéressant pour cet article. Pour les versions précédentes du framework, ce fichier est similaire.
Dorénavant tous les models, librairies, configs etc… seront stockés dans un lieu commun (le répertoire « bo ») et seront disponibles pour toutes les applications.
Conclusion
Cette technique permet de simuler un système de modules qui manque à CodeIgniter (bien qu’il existe des librairies le permettant, par exemple HMVC). Elle a l’avantage de fonctionner sur les versions antérieures à la 2.X du framework, alors qu’à partir de la version 2 on pourrait utiliser le système de « third_party » bien qu’il faille encore les charger « à la main ».
Happy coding !