Ecriture d'URLS normalisées et compatibles tout navigateur via PHP
Peut être avez-vous déjà été contraint de proposer des liens hypertextes d'accès à des fichiers utilisateurs incompatibles avec le protocole HTTP :
http://<host>:<port>/<path>?<searchpart>
Comme dans le cadre du listing d'un répertoire partagé sur un intranet avec des documents créés par des utilisateurs lambda, donc pas forcément au courant des bonnes pratiques de nommage des fichiers pour le web (qui pourrait les en blâmer?).
Prenons le cas concret d'une ressource « mondocument.pdf » dans un répertoire nommé « Documents Liés ».
Lorsque l'on ouvre directement la ressource dans le navigateur web en passant par le menu « fichier => ouvrir », le résultat dans la barre d'adresse sera différent suivant le navigateur utilisé.
Firefox affichera une URL formatée comme suit :
http://monserveur/Documents%20Li%E9s/mondocument.pdf
Tandis qu'Internet Explorer affichera :
http://monserveur/Documents%20Liés/mondocument.pdf
Maintenant, si l'on veut traduire cette URL dans une application, il nous faut un schéma d'accès correctement formaté pour les deux systèmes.
Suivant la norme rfc1738, une URL doit être encodée en utilisant le jeu de caractères US-ASCII. Lorsqu'il n'y a pas de correspondance entre un caractère et le jeu US-ASCII, il doit être déclarée en utilisant le caractère « % » suivi de sa représentation hexadécimale (deux chiffres de 0 à 9, de A à F : [0123456789ABCDEF]).
A la liste des caractères non présents dans le jeu US-ASCII, on prendra également soin d'encoder tout caractère dangereux (c'est à dire présentant des risques d'interprétation suivant le contexte, comme le cas des délimiteurs de chemins) dont voici la liste :
"{", "}", "|", "\", "^", "~", "[", "]", "`", " ", "#", "<", ">", "%", """
Pour obtenir une URL conforme à cette norme, PHP propose la fonction « rawurlencode() ».
Mais lisez cet extrait issu du fichier readme sur IE 6 (#Caractères non anglais dans les URL et les requêtes) :
« Internet Explorer 6 SP 1 utilise une nouvelle norme pour transmettre au serveur les adresses (URL) écrites en caractères non anglais. Les URL sont désormais codées selon la norme UTF-8. Si le serveur exécute Windows 2000, les URL sont interprétées de manière appropriée. De nombreux serveurs ne peuvent pas traiter les URL codées en UTF-8. »
Qu'à cela ne tienne, pour obtenir une URL « universelle », nous devrons préalablement prendre le soin d'encoder notre ressource avec le jeu de caractère UTF-8, ceci afin de supprimer les caractères LATIN-1, avant de la passer à la fonction « rawurlencode() ».
Toutes ces réflexions peuvent se traduire par la fonction PHP suivante :
function cleanURL($url){
$components = parse_url($url);
// Ressource invalide.
if (!isSet($components['path'])) {
return false;
}
$clean_path = implode('/', array_map('rawurlencode', explode('/', utf8_encode($components['path']))));
return str_replace($components['path'], $clean_path, $url);
}
Au final, notre exemple se traduira par l'URL :
http://monserveur/Documents%20Li%C3%A9s/mondocument.pdf
Et sera compatible avec tout système...
