Des pages d'erreur personnalisées avec Apache et PHP
URL de référence : http://www.apachefrance.com/Articles/7/
Pourquoi personnaliser ses pages d'erreur ?
"Butiner" sur le Web...j'adore cette expression. Non contente d'être
conforme avec les souhaits de l'Académie Française, elle apporte
un petit côté buccolique à la Grande Toile. Pourtant, n'y
a-t-il rien de moins buccolique qu'au cours d'un butinage en règle, une
triste page blanche vous annonce désespérément (et en Anglais)
"Error 404 : Page not found" ?
Heureusement, Apache vient à notre secours en proposant des mécanismes
simples et efficaces de personnalisation qui permettront d'agrémenter
les dites pages d'erreur d'une explication en Français, du logo de la
société ou encore du plan du site afin de permettre aux brebis
égarées de retrouver le chemin de la bergerie, à savoir
le contenu du site.
Le présent article a donc pour but de vous guider dans la mise en place
de pages d'erreur personnalisées sur vos sites.
Nous étudierons tout d'abord le mécanisme des codes de statut
HTTP, puis comment personnaliser Apache en fonction des codes d'erreur, puis
nous terminerons avec un exemple d'intégration avec PHP.
Les codes de statut HTTP
A chaque requête d'un client Web (i.e. le navigateur), le serveur Web
doit retourner à ce client un nombre comportant 3 chiffres appelé
code de statut HTTP. Un client Web peut ainsi tenter de comprendre la
réponse du serveur en examinant le code de statut, celui-ci parvenant
via l'en-tête Status-Line. Le code est accompagné d'une
courte phrase, nommée raison, qui doit fournir une brêve
explication à l'utilisateur. Par exemple, un en-tête HTTP Status-Line
peut ressembler à ceci :
HTTP/1.1 404 Not Found
"404" est ici le code d'erreur, et "Not found" la raison.
Sur un client Web, la phrase "Not Found" s'affiche dans la fenêtre
de navigation.
Il existe cinq classes de codes de statut dans les dernières spécifications
HTTP/1.1, dont les codes majeurs sont repris dans le tableau ci-dessous :
- 1xx : Codes d'information
- 2xx : Codes de succès
- 3xx : Codes de redirection
- 4xx : Code d'erreur client
- 5xx : Code d'erreur serveur
1xx : Codes d'information / Information codes |
| Code |
Statut / Status |
Description / Comment |
| 100 |
Continuer |
Attente de la suite de la requête.
La partie initiale de la requête a bien été reçue et le client peut continuer
avec la suite de cette requête. |
| Continue |
Waiting for the end part of the request.
The initial part of the request has been received and the client may continue
with its request. |
| 101 |
Changement de protocoles |
Le serveur accepte la requête du client de changer de protocole.
Le client a demandé au serveur d'utiliser un autre protocole que celui actuellement
utilisé, et le serveur accepte cette requête. |
| Switching Protocols |
The server is complying with a client request to switch protocols
to the one specified in the Upgrade header field.
The client asked the server to use another protocol than the one actually
used, and the server complied this request. |
2xx : Codes de succès / Success codes |
| Code |
Statut / Status |
Description / Comment |
| 200 |
OK |
La requête HTTP a été traitée avec succès.
L'information retournée avec la réponse dépend de la méthode utilisée dans
la requête. Par exemple la réponse à une requête GET classiquement émise
par un navigateur web sera la ressource demandée (c'est-à-dire une page
HTML, une image, etc). |
| OK |
The HTTP request has succeeded.
The information returned with the response is dependent on the method used
in the request. For example the response to a standard GET request issued
by a web browser is the requested resource (i.e. an HTML page, an image,
etc). |
| 201 |
Créé |
La requête a été correctement traitée et a résulté en la création d'une
nouvelle ressource.
Cette ressource peut être référencée par l'URI retournée dans le corps de
la réponse, avec l'URL la plus précise pour la ressource indiquée dans l'en-tête
du champ "Location". |
| Created |
The request has been fulfilled and resulted in a new resource being
created.
The newly created resource can be referenced by the URI(s) returned in the
entity of the response, with the most specific URL for the resource given
by a Location header field. |
| 202 |
Accepté |
La requête a été acceptée pour être traitée, mais son traitement peut
ne pas avoir abouti.
Ce code est utilisé en remplacement du 201 lorsque le traitement ne peut
pas avoir lieu immédiatement, son résultat est donc indéterminé. |
| Accepted |
The request has been accepted for processing, but the processing
has not been completed.
This code is used instead of 201 when the processing of the request cannot
be carried out immediately, leaving the result undetermined. |
| 203 |
Information non certifiée |
L'information retournée n'a pas été générée par le serveur HTTP mais
par une autre source non authentifiée.
|
| Non-Authoritative Information |
Usually the preliminary information sent from a server to a browser
comes directly from the server. If it does not, then this code might also
be sent to indicate that information did not come from a known source.
|
| 204 |
Pas de contenu |
Le serveur HTTP a correctement traité la requête mais il n'y a pas
d'information à envoyer en retour.
Cela peut par exemple se produire lorsqu'un fichier HTML ou le résultat
d'un programme CGI-BIN est vide. |
| No Content |
The request was accepted and filled but no new information is being
sent back.
The browser receiving this response should not change its screen display
(although new, and changed, private header information may be sent). |
| 205 |
Contenu réinitialisé |
Le client doit remettre à zéro le formulaire utilisé dans cette transaction.
Ce code est envoyé au logiciel de navigation quand il doit réinitialiser
un formulaire généré dynamiquement par un CGI-BIN, par exemple. |
| Reset Content |
The browser should clear the form used for this transaction for
additional input.
Appropriate for data-entry CGI applications. |
| 206 |
Contenu partiel |
Le serveur retourne une partie seulement de la taille demandée.
Ce code est utilisé lorsqu'une requête spécifiant une taille a été transmise. |
| Partial Content |
The server is returning partial data of the size requested.
Used in response to a request specifying a Range header. The server must
specify the range included in the response with the Content-Range header. |
3xx : Codes de redirection / Redirection codes |
| Code |
Statut / Status |
Description / Comment |
| 300 |
Choix multiples |
L'URI demandée concerne plus d'une ressource.
Par exemple, l'URI concerne un document qui a été traduit en plusieurs langues.
Le serveur doit retourner des informations indiquant comment choisir une
ressource précise. |
| Multiple Choices |
The requested URI refers to more than one resource.
For example, the URI could refer to a document that has been translated
into many languages. The entity body returned by the server could have a
list of more specific data about how to choose the correct resource. |
| 301 |
Changement d'adresse définitif |
La ressource demandée possède une nouvelle adresse (URI).
Toute référence future à cette ressource doit être faite en utilisant l'une
des URIs retournées dans la réponse. Le navigateur web doit normalement
charger automatiquement la ressource demandée à sa nouvelle adresse. |
| Moved Permanently |
The requested resource has been assigned a new permanent address
(URI).
Any future references to this resource should be done using one of the returned
URIs. Web browsers should automatically load the requested resource using
its new address. |
| 302 |
Changement d'adresse temporaire |
La ressource demandée réside temporairement à une adresse (URI) différente.
Cette redirection étant temporaire, le navigateur web doit continuer à utiliser
l'URI originale pour les requêtes futures. |
| Moved Temporarily |
The requested resource resides temporarily under a different URI.
Since the redirection may be altered on occasion, the client should continue
to use the Request-URI for future requests. |
| 303 |
Voir ailleurs |
L'URI spécifié est disponible à un autre URI et doit être demandé par
un GET.
|
| See Other |
The requested URI can be found at a different URI (specified in
the Location header) and should be retrieved by a GET on that resource.
|
| 304 |
Non modifié |
Le navigateur web a effectué une requête GET conditionnelle et l'accès
est autorisé, mais le document n'a pas été modifié.
Cette réponse classique signifie que vous avez configuré votre navigateur
pour utiliser un cache HTTP (proxy) dans lequel une copie du document demandé
est déjà stockée. Le proxy a donc demandé au serveur si le document original
a changé depuis, et a reçu cette réponse : il pourra ainsi utiliser la copie
locale. |
| Not Modified |
The web browser has performed a conditional GET request and access
is allowed, but the document has not been modified.
This classic response means you have configured your web browser to use
an HTTP cache (proxy) in which a copy of the requested document is already
stored. The cache proxy thus asked the server if the original document was
modified, and received this response, so it will use the local copy instead
of loading it from the server. |
| 305 |
Utiliser le proxy |
L'URI spécifié doit être accédé en passant par le proxy.
|
| Use Proxy |
The requested URI must be accessed through the proxy in the Location
header.
|
4xx : Erreur du client / Client Error |
| Code |
Statut / Status |
Description / Comment |
| 400 |
Mauvaise requête |
La requête HTTP n'a pas pu être comprise par le serveur en raison d'une
syntaxe erronée.
Le problème peut provenir d'un navigateur web trop récent ou d'un serveur
HTTP trop ancien. |
| Bad Request |
The HTTP request could not be understood by the server due to malformed
syntax.
The web browser may be too recent, or the HTTP server may be too old. |
| 401 |
Non autorisé |
La requête nécessite une identification de l'utilisateur.
Concrètement, cela signifie que tout ou partie du serveur contacté est protégé
par un mot de passe, qu'il faut indiquer au serveur pour pouvoir accéder
à son contenu. |
| Unauthorized |
The request requires user authentication.
This means that all or a part of the requested server is protected by a
password that should be given to the server to allow access to its contents. |
| 402 |
Paiement exigé |
Ce code n'est pas encore mis en oeuvre dans le protocole HTTP.
|
| Payment Required |
This code is not yet implemented in HTTP.
|
| 403 |
Interdit |
Le serveur HTTP a compris la requête, mais refuse de la traiter.
Ce code est généralement utilisé lorsqu'un serveur ne souhaite pas indiquer
pourquoi la requête a été rejetée, ou lorsqu'aucune autre réponse ne correspond
(par exemple le serveur est un Intranet et seules les machines du réseau
local sont autorisées à se connecter au serveur). |
| Forbidden |
The HTTP server understood the request, but is refusing to fulfill
it.
This status code is commonly used when the server does not wish to reveal
exactly why the request has been refused, or when no other response is applicable
(for example the server is an Intranet and only the LAN machines are authorized
to connect). |
| 404 |
Non trouvé |
Le serveur n'a rien trouvé qui corresponde à l'adresse (URI) demandée.
Cela signifie que l'URL que vous avez tapée ou cliquée est mauvaise ou obsolète
et ne correspond à aucun document existant sur le serveur (vous pouvez essayez
de supprimer progressivement les composants de l'URL en partant de la fin
pour éventuellement retrouver un chemin d'accès existant). |
| Not Found |
The server has not found anything matching the requested address
(URI).
This means the URL you have typed or cliked on is wrong or obsolete and
does not match any document existing on the server (you may try to gradualy
remove the URL components from the right to the left to eventualy retrieve
an existing path). |
| 405 |
Méthode non autorisée |
Ce code indique que la méthode utilisée par le client n'est pas supportée
pour cet URI.
|
| Method Not Allowed |
This code is given with the Allow header and indicates that the
method used by the client is not supported for this URI.
|
| 406 |
Aucun disponible |
L'adresse (URI) spécifiée existe, mais pas dans le format préféré du
client.
Le serveur indique en retour le langage et les types d'encodages disponibles
pour cette adresse. |
| Not Acceptable |
The URI specified by the client exists, but not in a format preferred
by the client.
Along with this code, the server provides the Content-Language, Content-Encoding,
and Content-Type headers. |
| 407 |
Authentification proxy exigée |
Le serveur proxy exige une authentification du client avant de transmettre
la requête.
|
| Proxy Authentication Required |
The proxy server needs to authorize the request before forwarding
it.
|
| 408 |
Requête hors-délai |
Le client n'a pas présenté une requête complète pendant le délai maximal
qui lui était imparti, et le serveur a abandonné la connexion.
|
| Request Time-out |
This response code means the client did not produce a full request
within some predetermined time (usually specified in the server's configuration),
and the server is disconnecting the network connection.
|
| 409 |
Conflit |
La requête entre en conflit avec une autre requête ou avec la configuration
du serveur.
Des informations sur les raisons de ce conflit doivent être indiquée en
retour. |
| Conflict |
This code indicates that the request conflicts with another request
or with the server's configuration.
Information about the conflict should be returned in the data portion of
the reply. |
| 410 |
Parti |
L'adresse (URI) demandée n'existe plus et a été définitivement supprimée
du serveur.
|
| Gone |
This code indicates that the requested URI no longer exists and
has been permanently removed from the server.
|
| 411 |
Longueur exigée |
Le serveur a besoin de connaître la taille de cette requête pour pouvoir
y répondre.
|
| Length Required |
The server will not accept the request without a Content-Length
header supplied in the request.
|
| 412 |
Précondition échouée |
Les conditions spécifiées dans la requête ne sont pas remplies.
|
| Precondition Failed |
The condition specified by one or more If... headers in the request
evaluated to false.
|
| 413 |
Corps de requête trop grand |
Le serveur ne peut traiter la requête car la taille de son contenu
est trop importante.
|
| Request Entity Too Large |
The server will not process the request because its entity body
is too large.
|
| 414 |
URI trop long |
Le serveur ne peut traiter la requête car la taille de l'objet (URI)
a retourner est trop importante.
|
| Request-URI Too Long |
The server will not process the request because its request URI
is too large.
|
| 415 |
Format non supporté |
Le serveur ne peut traiter la requête car son contenu est écrit dans
un format non supporté.
|
| Unsupported Media Type |
The server will not process the request because its entity body
is in an unsupported format.
|
| 416 |
Plage demandée invalide |
Le sous-ensemble de recherche spécifié est invalide.
|
| Requested range unsatifiable |
The server will not process the request because the requested range
is invalid.
|
| 417 |
Comportement erroné |
Le comportement prévu pour le serveur n'est pas supporté.
|
| Expectation failed |
The behavior expected fot the server is not supported.
|
5xx : Erreur du serveur / Server Error |
| Code |
Statut / Status |
Description / Comment |
| 500 |
Erreur interne du serveur |
Le serveur HTTP a rencontré une condition inattendue qui l'a empêché
de traiter la requête.
Cette erreur peut par exemple être le résultat d'une mauvaise configuration
du serveur, ou d'une ressource épuisée ou refusée au serveur sur la machine
hôte. |
| Internal Server Error |
The HTTP server encountered an unexpected condition which prevented
it from fulfilling the request.
For example this error can be caused by a serveur misconfiguration, or a
resource exhausted or denied to the server on the host machine. |
| 501 |
Non mis en oeuvre |
Le serveur HTTP ne supporte pas la fonctionnalité nécessaire pour traiter
la requête.
C'est la réponse émise lorsque le serveur ne reconnaît pas la méthode indiquée
dans la requête et n'est capable de la mettre en oeuvre pour aucune ressource
(soit le navigateur web est trop récent, soit le serveur HTTP est trop ancien). |
| Not Implemented |
The HTTP server does not support the functionality required to fulfill
the request.
This is the appropriate response when the server does not recognize the
request method and is not capable of supporting it for any resource (either
the web browser is too recent, or the HTTP server is too old). |
| 502 |
Mauvais intermédiaire |
Le serveur intermédiaire a fourni une réponse invalide.
Le serveur HTTP a agi en tant qu'intermédiaire (passerelle ou proxy) avec
un autre serveur, et a reçu de ce dernier une réponse invalide en essayant
de traiter la requête. |
| Bad Gateway |
The gateway server returned an invalid response.
The HTTP server, while acting as a gateway or proxy, received an invalid
response from the upstream server it accessed in attempting to fulfill the
request. |
| 503 |
Service indisponible |
Le serveur HTTP est actuellement incapable de traiter la requête en
raison d'une surcharge temporaire ou d'une opération de maintenance.
Cela sous-entend l'existence d'une condition temporaire qui sera levée après
un certain délai. |
| Service Unavailable |
The HTTP server is currently unable to handle the request due to
a temporary overloading or maintenance of the server.
The implication is that this is a temporary condition which will be alleviated
after some delay. |
| 504 |
Intermédiaire hors-délai |
Cette réponse est identique au code 408 (requête hors-délai), mais
ici c'est un proxy ou un autre intermédiaire qui a mis trop longtemps à
répondre.
|
| Gateway Time-out |
This response is like 408 (Request Time-out) except that a gateway
or proxy has timed out.
|
| 505 |
Version HTTP non supportée |
La version du protocole HTTP utilisée dans cette requête n'est pas
(ou plus) supportée par le serveur.
|
| HTTP Version not supported |
The server will not support the HTTP protocol version used in the
request.
|
Les codes de statut HTTP sont définis dans le RFC 2616, chapitre 10,
consultable ici.
Nous allons maintenant étudier comment définir des pages personnalisées
attachées aux codes de retour.
Configuration d'Apache
Lorsque la requête HTTP du client Web est considérée comme
une erreur par Apache, ou lorsqu'un problème survient suite à
l'exécution de cette requête, Apache peut réagir de 4 façons
différentes :
- afficher le message d'erreur standard
- afficher un message d'erreur personnalisé
- rediriger l'utilisateur vers une URL locale afin de traîter le problème
ou l'erreur
- rediriger l'utilisateur vers une URL externe afin de traîter le problème
ou l'erreur
Le premier comportement est celui par défaut d'Apache. Les autres comportements
seront possibles au travers de la directive ErrorDocument.
La directive
ErrorDocument
Celle-ci peut être défini au niveau du fichier httpd.conf (serveur
principal, hôtes virtuels, répertoires), mais, et c'est cette possibilité
qui intéressera la plupart d'entre vous, dans un fichier .htaccess.
Sa syntaxe est : ErrorDocument Code_d'Erreur message|URL
Afficher un
message d'erreur personnalisé
Pour afficher un message d'erreur personnalisé, il suffit de le saisir
au niveau du paramètre message, précédé d'un guillemet
(symbole "). Ce guillement ne figurera pas dans le message affiché.
Apache ajoutera également d'autres informations explicitant l'errreur.
Exemple
ErrorDocument 404 "Erreur 404 : La page n'existe pas !
Rediriger
l'utilisateur vers une URL locale/externe
L'unique différence entre la redirection vers une URL locale ou externe
réside dans la façon dont l'URL est écrite. Faire commencer
l'URL par "/" indiquera une URL locale, alors que pour une URL externe,
on fera précéder le chemin vers le document ou le script par "http://"
et le nom du serveur.
Exemples
ErrorDocument 404 /404.html
ErrorDocument 404 /404.php
ErrorDocument 500 /cgi-bin/errorHandler.pl
ErrorDocument 401 http://geldenhu.free.fr/401.html
ErrorDocument 404 http://geldenhu.free.fr/404.php
ErrorDocument 403 http://geldenhu.free.fr/erreur.php
Attention toutefois que, lors de l'utilisation d'une directive ErrorDocument
désignant une URL externe (donc commençant par "http://"),
Apache émettra une requête de redirection au client (catégorie
3xx) pour lui indiquer l'emplacement du document.
Ceci peut avoir pour effet de perturber les robots ainsi que certains clients
particuliers qui vérifient la validité d'une URL en testant le
code de retour de la requête.
Ajoutons également qu'en raison de la nature des mécanismes de
l'authentification HTTP, l'utilisation de la directive ErrorDocument avec le
code 401 (Accès non autorisé), nécessite de ne pas utiliser
d'URL externe. Dans le cas contraire, suite au code de redirection émis,
le client ne se verra pas présenter la demande d'authentification et
les pages seront inaccessibles.
Note pour les utilisateurs d'Internet Explorer
Internet Explorer 5 et supérieur incluent des pages d'erreur standards
présentées à l'internaute si le site Web ne propose pas
de pages personnalisées OU si la taille de ces pages est inférieure
à une certaine taille en octets (256 ou 512 selon le cas).
Pour contourner ce "problème", vous pouvez soit compléter
la page d'erreur avec des commentaires HTML afin d'atteindre 512 octets, soit
opter pour l'une des deux modifications suivantes dans Internet Explorer :
• Dans les options d'Internet Explorer, onglet "Avancés",
décocher la case "Afficher des messages d'erreur HTTP simplifiés",
• Dans la base de registre, rechercher le dossier HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet
Explorer\Main\ErrorThresholds. Vous trouverez alors plusieurs entrées
correspondant à un code HTTP et la taille de page minimum attendue pour
afficher la page du site plutôt que la page interne d'IE.
Référence : Description
des messages d'erreur HTTP, Microsoft.
Plus
loin dans la personnalisation...
Comme nous venons de l'évoquer, l'URL peut désigner aussi bien
une page statique qu'un script "côté serveur" écrit
avec PHP ou encore un CGI écrit en Perl. Cependant, cette possibilité
sera d'autant plus intéressante que certaines informations concernant
l'environnement et les raisons précises de l'erreur seront disponibles,
dans le but de délivrer le message le plus clair possible.
Nous en avons rêvé, Apache l'a fait. Ainsi, les variables d'environnement
CGI suivantes seront disponibles :
- REDIRECT_HTTP_ACCEPT (type MIME acceptés par le client)
- REDIRECT_HTTP_USER_AGENT (description du navigateur client)
- REDIRECT_PATH (chemin de recherche des binaires sur le serveur)
- REDIRECT_REMOTE_ADDR (adresse IP du client)
- REDIRECT_REMOTE_HOST (nom qualifié du client si disponible)
- REDIRECT_SERVER_NAME (nom qualifié ou adresse IP du serveur)
- REDIRECT_SERVER_PORT (port TCP/IP utilisé par le serveur pour "écouter"
les requêtes)
- REDIRECT_SERVER_SOFTWARE (description du serveur HTTP utilisé)
- REDIRECT_URL (URL ayant conduit à l'URL actuelle)
- REDIRECT_QUERY_STRING (paramètres de formulaire passés via
l'URL)
- REDIRECT_STATUS (code HTTP du statut)
Plusieurs éléments clés sont à prendre en compte
:
- toutes les variables sont préfixées par la chaîne "REDIRECT_",
- ces variables n'existeront que si elles existaient sous leur forme non préfixée
préalablement au traitement de l'erreur,
- les variables REDIRECT_URL et REDIRECT_STATUS seront quant à elles
toujours renseignées ; REDIRECT_QUERY_STRING sera vide à moins
que des paramètres soient passés au script/CGI via l'URL de
redirection,
- aucune des deux variables précédemment citées ne sera
initialisée si le document d'erreur est le résultat d'une redirection
externe, c'est-à-dire débutant par "http://". Ceci
est valable même si le site cible est le même que le site d'origine
de la redirection.
Nous allons maintenant étudier comment utiliser au mieux la directive
ErrorDocument et cet environnement CGI au travers de PHP.
Intégration avec PHP
Cette dernière partie décrit une façon de récupérer
les principales erreurs et de proposer un affichage personnalisé en s'appuyant
sur PHP. Le mécanisme décrit est celui employé sur Apache
France.
Paramétrage
d'Apache
L'hypothèse de départ est que nous souhaitons disposer des pages
d'erreur personnalisées sur l'ensemble du site pour les erreurs les plus
communes :
- 401 : Authentification nécessaire
- 403 : Accès interdit
- 404 : La page spécifiée n'existe pas
- 500 : Erreur interne du serveur
Nous souhaitons également traiter les erreurs dans un script unique,
écrit en PHP, que nous appelerons erreur.php.
ErrorDocument 401 /erreur.php
ErrorDocument 403 /erreur.php
ErrorDocument 404 /erreur.php
ErrorDocument 500 /erreur.php
Comme indiqué précédemment lors de la présentation
de la directive, les lignes de configuration seront ajoutées soit dans
le fichier httpd.conf dans la section du site principal, soit dans le fichier
httpd.conf dans la section des hôtes virtuels, pour un site particulier,
soit dans un fichier .htaccess qui sera placé à la racine de l'arborescence.
Pour protéger l'accès malencontreux à certaines fichiers
(et tester la personnalisation de l'erreur 403), nous allons également
désactiver le listing de répertoires via la directive Option et
le paramètre -Indexes.
Options -Indexes
Cette directive est à utiliser soit au niveau d'un bloc "Directory"
correspondant à la racine de votre arborescence (httpd.conf), soit directement
(fichier.htaccess).
Voici par exemple le fichier .htaccess utilisé sur Apache France :
ErrorDocument 401 /erreur.php
ErrorDocument 403 /erreur.php
ErrorDocument 404 /erreur.php
ErrorDocument 500 /erreur.php
Options -Indexes
Certains hébergeurs limitent ou désactivent l'utilisation des
fichiers .htaccess. Ainsi, Free.fr autorise un fichier .htaccess avec les directives
ErrorDocument, mais les redirections ne sont autorisées que vers des
pages statiques.
Présentation
du script Erreur.php
Le script Erreur.php est chargé de l'affichage d'un message d'erreur
explicit en fonction de l'erreur commise par l'internaute ou du problème
rencontré par le serveur.
Vu qu'il n'y a qu'un seul script pour toutes les erreurs, il faudra donc récupérer
les variables CGI nécessaires. Nous n'avons besoin que de REDIRECT_STATUS,
qui nous permettra de déterminer le code d'erreur. L'autre variable utile,
REQUEST_URI (il s'agit bien d'un i majuscule), est propre à PHP et contient
l'URL demandée par l'internaute. Par exemple, si ce dernier a demandé
la page http://www.monsite.com/toto/titi.html, REQUEST_URI contient "/toto/titi.html".
Nous avons également choisi d'utiliser les
super variables globales introduites avec PHP 4.1. Dans ce cas, REQUEST_URI
et REDIRECT_STATUS sont disponibles via le tableau associatif $_SERVER. Si vous
disposez d'une version antérieure ou que les super variables globales
sont désactivées, il suffit de profiter du mécanisme d'instanciation
automatique des variables CGI sous forme de variables locales : $REQUEST_URI
et $REDIRECT_STATUS.
Nous allons maitenant étudier le script Erreur.php.
Etude du script
Erreur.php
Tout d'abord, afin de protéger le script, nous testons l'existence de
la variable REDIRECT_STATUS.
if (!isset($_SERVER["REDIRECT_STATUS"])) Header("Location:
/");
Si elle existe, nous sommes redirigés vers le script suite à
une erreur Apache : tout va bien, l'exécution du script continue. Dans
le cas contraire, un internaute fait un appel direct au script : nous effectuons
une redirection vers la racine du site via la fonction PHP header().
Après avoir "requis" certains librairies/fichiers, nous allons
décrire un tableau associatif associant un message spécifique
à un code d'erreur.
$source_erreur = $_SERVER["REQUEST_URI"];
$code_erreur = $_SERVER["REDIRECT_STATUS"];
$cause_erreur['401'] = "Authentification
nécessaire";
$cause_erreur['403'] = "Accès
interdit";
$cause_erreur['404'] = "La
page spécifiée n'existe pas";
$cause_erreur['500'] = "Erreur
interne du serveur";
$libelle_erreur = "Erreur $code_erreur";
Pour plus de facilité, nous récupérons l'URL demandée
et le code d'erreur respectivement dans les variables $source_erreur et $code_erreur.
Le tableau associatif $cause_erreur permettra de faire le lien.
Après l'affichage de l'en-tête ( showHeader() ), nous écrivons
le corps de la page qui sera personnalisé par l'affichage de l'URL à
la source de l'erreur, du code d'erreur, et du message d'erreur correspondant.
echo "$source_erreur : $libelle_erreur : $cause_erreur[$code_erreur]";
Enfin, nous affichons le pied de page ( showFooter() ).
Voici le script Erreur.php complet :
<?
if (!isset($_SERVER["REDIRECT_STATUS"])) Header("Location:
/");
require_once('articles.inc.php');
$source_erreur = $_SERVER["REQUEST_URI"];
$code_erreur = $_SERVER["REDIRECT_STATUS"];
$cause_erreur['401'] = "Authentification
nécessaire";
$cause_erreur['403'] = "Accès
interdit";
$cause_erreur['404'] = "La
page spécifiée n'existe pas";
$cause_erreur['500'] = "Erreur
interne du serveur";
$libelle_erreur = "Erreur $code_erreur";
showHeader($libelle_erreur,0);
?>
<p><span class=grosTitre><?php echo "$source_erreur : $libelle_erreur : $cause_erreur[$code_erreur]"; ?></span></p>
<p>Si cette page est présentée suite au clic sur
un lien ou un tout
autre élément devant conduire à
une page existante, n'hésitez
pas à nous en faire part en cliquant <a href="/Contact/">ici</a>,
nous
ferons rapidement le nécessaire.<br>
<br>
Nous vous remercions pour votre compréhension.<br>
<br>
Cliquer <a href="/">ici</a> pour retourner à
l'accueil.</p>
<?
showFooter(0);
?>
Vous pouvez avoir un aperçu des pages générées
ici (erreur
403) ou bien ici
(erreur 404).
Conclusion
Vous connaissez désormais les possibilités de personnalisation
des pages d'erreur qu'offrent Apache et PHP. Pour toute question ou remarque
complémentaire, rendez-vous dans le forum !.
Remarques
La présentation du code HTTP est inspirée du livre Apache
Server de M.J.Kabir.
Les codes HTTP sont extraits du site INDEXA.
Les informations pour la personnalisation sont inspirée de la documentation
d'Apache.
|