Teddy Payet
CTO Freelance

SPIP, les erreurs 404 et consorts…

Suite à une discussion avec un collègue drupalien, je me suis demandé quelles sont les solutions sur SPIP pour lister les erreurs 404. J’en ai profité pour lancer une discussion sur le sujet dans la communauté SPIP pour avoir des retours sur l’existant.

Préambule

Cet article va me servir surtout de poser mes phases de réflexion sur la détection et le "suivi" des erreurs 404 au sein de SPIP. Mais cette problématique peut aussi être portée sur d’autres systèmes, d’autres CMS.
La conversation que j’ai eu sur la liste de SPIP-Zone sur cette problématique peut-être lue ici : http://www.mail-archive.com/spip-zone@rezo.net/msg39670.html

Besoin de départ

Le but est de pouvoir lister aisément et simplement les erreurs 404 qui ont eu lieu sur le site. Cela pour plusieurs raisons :

  • comprendre ce qui a amené à ces 404 ;
  • faire des redirections d’anciennes urls vers les nouvelles ;
  • développer de nouvelles solutions pour ces urls précises (un peu de fun, ça ne fait pas de mal).

Recherches

Avant de voir ce qu’on peut faire avec SPIP, j’ai regardé ce qu’il y a chez les autres…

Wordpress
Chez Wordpress, comme on peut s’y attendre, il y a une flopée de plugins pour gérer les 404. Il suffit de voir la page de résultats de recherche des plugins : https://fr.wordpress.org/plugins/search.php?q=404
748 résultats… Beaucoup de ces plugins servent à rediriger les 404 vers une 301. Et bien entendu, c’est dans un soucis de qualité SEO.
Celui que je retiens dans ces plugins est "404 to 301". Il a l’air très complet. Il stocke dans une table les erreurs 404 pour pouvoir avoir un historique.

Drupal
Pour Drupal, tout est stocké en base de données par défaut. Donc, il y a déjà une information à traiter et filtrer selon les besoins.
Pourtant, la recherche pour des fonctionnalités complémentaires est plus "floue" pour moi. Les fonctionnalités des plugins remontés par la page de recherche. De ce que je vois des différentes descriptions des modules, on fait un tracking des 404 par le biais des analytics (Google Analytics, Piwik, etc.) ou une personnalisation des pages 404.
Après discussion avec mon collègue drupalien, on utilise souvent le plugin Fast 404 pour desservir plus rapidement (étonnant ?) les pages 404. Et quand on désire faire des redirections, on utilise le module Redirect.

Joomla
La recherche remonte beaucoup de plugins, payant ou gratuit : http://extensions.joomla.org/extensions/extension?searchall=404&dir=DESC&limitstart=&controller=filter&view=extension&layout=list&Itemid=145&clearorders=0&clearfilters=1
Le premier plugin Fix 404 error links stocke les erreurs 404 et permet de les rediriger une par une vers une page qu’on aura défini dans l’espace privé du site.

Les frameworks
Pour Symfony comme pour CakePHP, je n’ai pas trouvé de modules permettant la gestion des 404. Une recherche Google me remonte surtout des articles sur comment personnaliser une page d’erreur 404.

Retour sur la conversation sur la liste SPIP-Zone

Comme je l’avais dit au début de cet article, j’ai initié une discussion sur la liste SPIP-Zone avec les personnes de la communauté.

RealET fait remonter la solution qu’il utilise dans SoyezCréateur. La page 404 crée un log dédié aux erreurs 404. Cette solution est simple et efficace. Toutefois, je lui trouve un soucis… C’est qu’un fichier log peut être supprimé. De plus, les logs ne sont pas consultés dans l’espace privé dans sa solution. Mais ça, on peut le palier avec le plugin Simples Logs

D’autres personnes de la communauté remontent le fait que le serveur (Apache, Nginx et Cie) stocke déjà ce genre d’informations dans les logs. Ce qui est classique et de façon légère contrairement à des solutions à base de langage interprété (cf. PHP).
En effet, ils ont raisons. Mais selon l’hébergeur, nous n’avons pas toujours accès à ces logs en "temps réel". Le temps de demander les logs, on perd de la réactivité.

Phase de réflexion

En règle générale, lorsque les solutions déjà en place stockent en base de données les erreurs 404, les éléments enregistrés sont :

  • L’url amenant à l’erreur ;
  • Le numéro de l’erreur ;
  • Le message d’erreur ;
  • L’adresse IP ;
  • Le pays ;
  • Les informations sur le navigateur et le système d’exploitation ;

Sur ces solutions, pour celles qui gèrent la redirection, il est possible de renseigner une url vers laquelle sera redirigée l’erreur 404.

Bien entendu, pour chacune de ces solutions, il faut que le serveur redirige les erreurs 404 vers une page dédiée au lieu d’afficher un message par défaut.

Solution #1

La solution la plus efficace, comme partagée par la communauté, est de lire les logs du serveur. Ce n’est pas forcément accessible à tout le monde. Il faudrait pouvoir "vulgariser" un message brut d’un serveur pour le rendre compréhensible pour des néophytes.

Cela a le mérite d’être léger. Une bonne expression régulière pourra amener l’interprétation adéquate.
Si on désire réaliser des redirections, il faudra donc lister les urls désirés et insérer dans un fichier .htaccess une redirection. Ceci est à faire par un administrateur du serveur et ne peut être fait par un utilisateur lambda.

La difficulté sera de trouver comment utiliser les logs serveurs (s’ils sont accessibles) pour y greffer des fonctionnalités telles que la redirection par exemple.

Solution #2

On peut stocker chaque erreur 404 dans la base de données pour la visualiser le plus simplement dans l’espace privé. Il y a des pour et des contre sur le fait d’écrire en base de données au lieu de stocker dans un fichier sur le serveur.

Sur des hébergements mutualisés, il est parfois plus rapide d’écrire dans la base de données que sur le disque dur. Mais on peut concilier les 2 procédures : stocker dans un fichier sur le serveur et à période régulière, on stocke le contenu dans la base de données.

De plus, le fait de stocker ces erreurs permettrait d’indiquer une url de redirection si l’utilisateur le désire. Une fonction supplémentaire à notre solution.

Mais qui dit base de données, dit table, et donc on doit définir nos champs. Je prend l’exemple de SPIP, mais je l’ai dit, on peut reporter cette problématique selon d’autres systèmes. Voici une structure de table "spip_erreurs" :

  • id_erreur : BIGINT(21), l’identifiant unique de l’erreur ;
  • date : DATETIME, date à laquelle l’erreur s’est produite ;
  • url : VARCHAR(255), l’url qui a amené à cette erreur récupéré par $_SERVER['REQUEST_URI'] ;
  • ref : tinytext, $_SERVER['HTTP_REFERER'], si renseigné, retrouver l’url qui a amené à cette erreur ;
  • ip : VARCHAR(45), l’adresse IP du visiteur ayant été sur cette page d’erreur. On fera un test sur HTTP_CLIENT_IP, ou HTTP_X_FORWARDED_FOR ou REMOTE_ADDR pour en récupérer l’adresse désirée.
  • ua : tinytext, on stocke l’information sur le user agent grâce à $_SERVER['HTTP_USER_AGENT'] ;
  • code : VARCHAR(25), on va stocker une information liée à l’entête de la page telle que "404 Not Found" ;
  • status : VARCHAR(3), ici on stocke le numéro de l’erreur. On essaie de faire cette table générique, même si notre problématique est pour les 404.

En complément
Avec cette structure, je pense qu’on prêt pour une mise en place. Mais il manque tout de même un aspect : doit-on stocker à chaque fois l’erreur d’une url dans la base de données ? Ou peut-on envisager un simple incrément d’un compteur ? Pour l’incrément, le champ compteur répondra à l’affaire (INT comme définition SQL).

Et pour la redirection, le fait de n’avoir qu’une entrée pour une url, limitera le nombre de requêtes dans la base de données, simplifie la recherche. Pour la redirection, on peut imaginer avoir un champ dédié que le visiteur mettra à jour à sa convenance. Le nom du champ est tout trouvé : redirect.

Implémentation
Il y a plusieurs possibilités :

  1. Utilisation d’une fonction que le webmaster insérera dans son template ;
  2. Utilisation d’une API qui permet de s’insérer dans la page que l’on désire ;
  3. Fournir un template par défaut pour la page 404.

Pour le point 1, la solution ne sera pas plug and play pour l’utilisateur lambda. Cela peut être un inconvénient.
Pour le point 2, il faut voir si en passant par l’API, on réussit à récupérer les données de la super globale $_SERVER. PHP étant bien fait, cela ne devrait pas posé de problème, mais il faut tester pour ne pas avoir de surprise.
Pour le point 3, le template n’est pas forcément adapté au design du site qui l’utilisera. Et ce n’est pas le but.

Le point 2 semble donc le plus adapté par rapport aux autres.