Générer une erreur 404 avec CakePHP

Nous souhaitons verrouiller les actions de consultation de nos Contrôleurs pour pouvoir répondre de façon consistante à toute requête inattendue pour optimiser le référencement du site. En effet, nous ne voulons pas qu’un lien incorrect venant d’un site tiers renvoie un code 200 OK, qui ferait penser à un moteur de recherche qui suivrait ce lien que la page indiquée existe toujours. Nous devons identifier une requête ne donnant pas ou plus de résultat en renvoyant un code 404 avec la méthode cakeError.

1. Dans le Contrôleur

Prenons l’exemple d’un catalogue de produits. Nous avons un Contrôleur ProduitsController et deux actions : index et view, respectivement pour lister les produits et consulter la fiche détaillée d’un produit. Voyons l’action view :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// {app}/controllers/produits_controller.php
function view($id = null)
{
  if(!$id)
  {
    $this->redirect(array('action' => 'index'), 301);
  }
 
  $produit = $this->Produit->findById(intval($id));
 
  if(empty($produit))
  {
    $this->cakeError('error404', array(array('url' => $this->action)));
  }
 
  $this->set('produit', $produit);
}

Reprenons en détail :

4
5
6
7
if(!$id)
{
  $this->redirect(array('action' => 'index'), 301);
}

Si aucun id n’est transmis ou s’il est égal à 0, on renvoie le visiteur sur l’action index, soit la liste des articles. Si le visiteur est un moteur de recherche, arrivant d’un site tiers qui contient un lien incorrect vers notre site, on lui envoie en plus un code 301 Moved Permanently (« la page demandée est définitivement remplacée par celle d’arrivée »), qui va lui permettre de mettre son index à jour et de « déréférencer » la page /produits/view/.

9
$produit = $this->Produit->findById(intval($id));

On recherche un produit qui aurait un id égal à la valeur entière du paramètre passé dans l’url.

11
12
13
14
if(empty($produit))
{
  $this->cakeError('error404', array(array('url' => $this->action)));
}

Si la base ne renvoie aucun enregistrement, c’est que le produit n’existe pas ou plus, on appelle donc une méthode spéciale de CakePHP pour générer une erreur 404, cakeError. Nous sommes obligé de définir le 2ème paramètre de cette méthode, array(array('url' => $this->action)), même si nous ne l’utiliserons pas dans la vue d’erreur. En effet, la méthode cakeError construit un message d’erreur en fonction de l’action du Contrôleur qui l’a appelée, mais ce message est en anglais, nous allons donc le définir nous-même dans la Vue.

2. Dans la Vue

Il ne nous reste qu’à créer le fichier {app}/views/errors/error404.ctp, dans laquelle nous informons le visiteur que la ressource demandée est indisponible, et nous lui affichons le plan du site afin qu’il puisse continuer sa visite. Si le visiteur est un moteur, il recevra en plus le code 404 Not Found et n’indexera pas la page en question, et le fait de lui afficher le plan du site va lui permettre à lui aussi de continuer sa visite, donc son indexation.

1
2
3
4
5
6
7
// {app}/views/errors/error404.ctp
<?php
$this->pageTitle = "Erreur 404 : page introuvable";
?>
<h1>Page introuvable</h1>
<p>La page que vous recherchez est introuvable.</p>
<?php e($this->element('sitemap')); ?>
Pierre-Emmanuel Fringant

Commentaires

Apparement il est possible de traduire le message d’erreur 404 de cakephp mais cela veut dire d’inclure tous les messages gettext de l’arborescence cake/, ce qui peut sembler lourd (notamment quand on doit après chercher quelles chaînes de caractères appartiennent à notre vrai site et celles utilisées par cakephp pour du debug).

Hébergeur lesCigales.ORG http://www.lescigales.org/

On peut enrichir le fonctionnement en plaçant tout ça dans une fonction checkIf404() (ou autre appellation, je suis pas rigide ;) ) du app_controller.php, que l’on appelle pour toutes les vues edit / view…

Participez

Pour insérer une portion de code, utilisez <pre lang="php">...</pre>