Contrôleur non trouvé
Une erreur peut se produire et rendre le comportement de votre application inattendue lorsqu’un fichier est manquant. Ce fichier peut être une image, une feuille de styles CSS, un favicon.ico ou tout autre généralement placé dans le répertoire /public de l’arborescence du framework.
L’erreur retournée est levée par une exception du type Zend_Controller_Dispatcher_Exception et retourne le message ci-dessous (exemple d’un fichier favicon.ico manquant) :
Zend_Controller_Dispatcher_Exception: Invalid controller specified (favicon.ico)
Le plus simple est dans ce cas d’ajouter le fichier manquant.
Principe des règles de réécriture d’URL
Fichier .htaccess
La raison de ce problème vient des règles de réécriture d’URL telles que proposées sur le site de Zend Framework à l’URL http://framework.zend.com/manual/fr/zend.controller.router.html.
Ci-dessous les règles de réécriture pour Apache, à placer dans un fichier .htaccess, dans le répertoire /public de l’application :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Regardons rapidement ensemble les directives ci-dessus.
Directive RewriteEngine
La première directive RewriteEngine est placée à la valeur On. Elle active simplement le moteur de réécriture d’URL d’Apache.
Directives RewriteCond
Les directives commençant par RewriteCond vont conditionner l’exécution de la directive RewriteRule qui suit.
Dans notre cas, le test se fait sur la variable serveur REQUEST_FILENAME qui contient le chemin d’accès absolu à un script ou un fichier correspondant à la requête courante.
Cette chaîne à tester est immédiatement suivie de la condition à effectuer.
La condition -s (is regular file with size) permet de vérifier l’existence d’un fichier dont le poids est strictement supérieur à 0 octet.
La condition -l (symbolic link) permet de vérifier l’existence d’un lien symbolique.
La condition -d (is directory) permet de vérifier l’existence d’un répertoire.
Par défaut, les conditions imposées par les directives RewriteCond se combinent (AND). Si l’on souhaite tester une des conditions, il faut alors placer le flag [OR] en fin de directive.
Directives RewriteRule
Les directives RewriteRule sont celles qui définissent la règle de réécriture elle-même.
La première d’entre elles :
RewriteRule ^.*$ - [NC,L]
ne fait qu’indiquer qu’il ne faut rien faire (c’est ce qu’indique le tiret placé juste avant les flags NC et L) si les conditions imposées par les directives RewriteCond qui précèdent sont remplies.
La suivante :
RewriteRule ^.*$ index.php [NC,L]
qui sera exécutée dans tous les autres cas redirige vers le Front Controller de notre application, c’est-à-dire le fichier index.php.
Ces directives possèdent dans notre cas des flags (ils apparaissent entre crochets).
Le flag NC correspond à No Case, ce qui rend la comparaison insensible à la casse.
Le flag L correspond à Last. Ceci signifie que si la règle de réécriture correspondante est réalisée, alors toutes celles qui suivent ne seront pas interprétées.
Modifier les règles de réécriture d’URL
De façon plus générale, et afin d’éviter les levées d’exceptions, je vous propose de modifier votre fichier .htaccess comme ci-dessous :
RewriteEngine On
RewriteRule ^\/?styles.*$ - [NC,L]
RewriteRule ^\/?media.*$ - [NC,L]
RewriteRule ^\/?js.*$ - [NC,L]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Le principe est de regarder tous les répertoires qui sont placés dans le répertoire /public de votre application puis d’utiliser des directives RewriteRule pour indiquer que ces répertoires et tout ce qui s’y trouve ne doivent pas être redirigé vers le Front Controller (index.php). Ils continueront ainsi à être considérés comme des répertoires et des fichiers, même si l’un d’entre eux n’existe pas.
C’est ce que je viens de faire en ajoutant les trois directives ci-dessous :
RewriteRule ^\/?styles.*$ - [NC,L]
RewriteRule ^\/?media.*$ - [NC,L]
RewriteRule ^\/?js.*$ - [NC,L]
à mon fichier .htaccess.
Dans mon cas, ces réécritures d’URL ont été faites pour les répertoires styles, media et js.
Les expressions régulières utilisées pour trouver les chaînes de texte se décomposent comme suit :
^ pour indiquer le début de la chaîne ;
\/? pour indiquer la présence facultative du / de début de chaîne ;
.* pour indiquer n’importe quel caractère (présent ou non) ;
$ pour indiquer la fin de la chaîne.
Entre ^\/? et .*$, se trouve le nom du répertoire à traiter.
Conclusion
Du coup, avec ces nouvelles règles de réécriture d’URL, lorsqu’on essaie d’accéder à un répertoire ou à un fichier contenu dans styles, media ou js, une erreur 404 (page manquante) est retournée par Apache. A vous de la traiter correctement pour obtenir un résultat professionnel !
Ces ajouts dans le fichier .htaccess nous permettent surtout d’éviter des problèmes lors de l’emploi des méthodes du Zend Framework qui manipulent les requêtes HTTP, comme getRequestUri() ou bien d’autres.