Avec la popularisation de Twitter, il n'y a jamais eu autant de services en ligne permettant de raccourcir les URL. Très pratique lorsqu'il s'agit d'économiser de la place dans un tweet, ces URL possèdent néanmoins un gros défaut: il n'est pas possible de savoir avec précision où l'URL emmène. Pour résoudre cette problématique, ce tutorial présente un script AJAX qui permet de dé-raccourcir une URL.

Présentation

Une page d'exemple est disponible. Notez toutefois que le script n'a pas été testé avec tous les services permettant de raccourcir une URL. Il fonctionne uniquement sur les raccourcisseurs d'URL qui font des redirections 301 ou 302 (redirection Javascript pas prise en compte par le script).

Prérequis

Il est préférable d'avoir des connaissances en AJAX pour pouvoir comprendre le script. Cependant en connaissant uniquement le PHP, il est possible de comprendre à peu près le script. Dans les archives de ce blog il est possible de découvrir des tutoriaux d'initiation qui sont parfait pour les débutants. N'hésitez pas par exemple à consulter les articles de la catégorie AJAX.

Code

Code xHTML

Le code xHTML est assez simple, il faut juste avoir un formulaire pour envoyer la petite URL et un <div> pour pouvoir afficher le résultat dynamiquement (avec Javascript).

<form method="post" action="" enctype="multipart/form-data">
<label>URL: <input type="text" name="url" id="url" /></label> <input onclick="displayURL(url.value)" type="button" value="Dé-raccourcir l'URL" />
</form>

<div id="afficherURL"></div>

Code Javascript

Le code Javascript est un peu élaboré puisqu'il doit récupérer les informations dynamiquement.

function file(fichier)
{
 if(window.XMLHttpRequest) // FIREFOX
 xhr_object = new XMLHttpRequest();
 else if(window.ActiveXObject) // IE
 xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
 else
 return(false);
 xhr_object.open("GET", fichier, false);
 xhr_object.send(null);
 if(xhr_object.readyState == 4) return(xhr_object.responseText);
 else return(false);
}

function displayURL(url)
{
 // Afficher une image pendant le chargement
 window.document.getElementById("afficherURL").innerHTML = "<img src=\"Loading-transparent.gif\" alt=\"icône chargement\" />";

 if (url != false){ /* Si l'utilisateur à bien inscrit l'URL */
 var url = "afficher-url.php?url="+url; /* Adresse du fichier .php */
 var obj = file(url); /* Récupère le résultat (la longue URL) */
 /* le résultat est affiché dans un div (.result) qu'il est possible de personnaliser avec CSS */
 window.document.getElementById("afficherURL").innerHTML = "<div class=\"result\">"+obj+"</div>";
}
else
 window.document.getElementById("afficherURL").innerHTML = "Erreur";
}

Note: L'image de chargement est la suivante (vous pouvez la prendre elle est libre de droit):

Image de chargement avec AJAX

Code PHP

Version 1 (nécessite PHP 5)

Ce code est une mise à jour de l'article suite à la suggestion de Seebz dans les commentaires. Il existe une fonction en PHP 5 intitulé get_headers(). Cette dernière facilite grandement le script.

<?php
$url=trim(strip_tags($_GET['url']));

function analyseur_header_http($url)
{
 $headers = get_headers($url,1);
 if (is_array($headers['Location'])) // Retourne true si $headers['Location'] est un array
 return end($headers['Location']);
 else
 return $headers['Location'];
}

$url_retour = analyseur_header_http($url);
echo '<a href="'.$url_retour.'">'.$url_retour.'</a>';
?>

Cette fonction à l'avantage de retourner la dernière URL dans le cas où il y a plusieurs redirection à la suite.

Version 2 (idéal pour PHP 4)

Ce code alternatif est est un peu moins efficace mais il est pratique dans le cas où vous n'avez pas PHP 5. Le code utilise curl pour extraire le contenu de la page.  Il faut donc s'assurer dans un premier temps que l'hébergeur accepte l'utilisation de cette ressource (certains hébergeurs empêchent l'utilisation de cette ressource qui consomme trop). L'extraction de la page sert à récupérer le texte inclue dans l'entête HTTP. C'est dans cet entête qu'il y a la page de redirection (la longue URL). Le code PHP récupère alors cette adresse et l'affiche pour qu'elle soit utilisée dans le fichier Javascript.

<?php
$url=trim(strip_tags($_GET['url']));

function analyseur_header_http($url)
{
 $ch = curl_init(); // Initialise une nouvelle session cURL

 // Options de transfert cURL
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_HEADER, true);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);

 $en_tete = curl_exec($ch); // Exécute la session cURL

 curl_close($ch); // Fermeture cURL

 if ($en_tete==true){
 $position = strpos($en_tete, '<'); // récupère la position du caractère "<"
 $en_tete = substr($en_tete, 0, $position); // récupère seulement l'entête HTTP
 }

 $en_tete = nl2br($en_tete);
 preg_match('#Location: (.+)\<br /\>#isU', $en_tete, $url_retour_array); // Extraire l'URL
 $url_retour = '<a href="'.$url_retour_array[1].'">'.$url_retour_array[1].'</a>';

 return $url_retour; // Retourne l'URL entière
}

echo analyseur_header_http($url); // Utilisation de la fonction analyseur_header_http()
?>

Télécharger le script

Pour éviter de se perdre avec les fichiers et les différents scripts, un fichier zippé contenant tout ce qui est nécessaire à l'exécution du script peut être téléchargé:

L'utilisation est simple. Il suffit de décompresser les fichiers et de les uploader sur un site web.

Commentaires

Salut,
PHP5 offre une nouvelle fonction get_headers() qui pourrait "alléger" votre fonction analyseur_header_http() :

function analyseur_header_http($url)
{
$headers = get_headers($url,1);
return end($headers['Location']);
}

De cette manière, on obtiendra réellement l'url finale (même s'il y a plusieurs redirections consécutives) ou false si l'url fournie est l'url final (pas de redirection).

Seebz - 31 janvier 2010 à 17h20

@Seebz: Excellent, merci pour l'information. Ayant anciennement l'habitude d'utiliser PHP 4 je ne connaissais pas du tout la fonction get_headers(). Merci d'avoir commenté l'article pour faire partager l'information.

Edit: J'ai mis à jour l'article avec ta suggestion. J'ai cependant apporté une légère modification. En effet, la fonction end() ne fonctionne que si son paramètre est un Array. S'il n'y a qu'une seule redirection, le paramètre n'est pas un Array et le code ne fonctionne donc pas. Pour corriger le problème j'ai utilisé is_array().
Merci encore pour l'information.

Tony - 31 janvier 2010 à 19h29

Bien vu pour la correction, j'ai écris ça sur le tas et n'ai pas pris le temps de tester.

Bonne continuation ;)

ps: du coup la fonction analyseur_header_http() retournera null (et pas false) si l'url passée en argument n'est pas une redirection

seebz - 1 février 2010 à 09h21

@Seebz: Pas de soucis. Merci pour le complément d'information.

Tony - 1 février 2010 à 13h32

Trackbacks

[...] Cet article va présenter uniquement le code PHP pour utiliser l'API de Untiny. Le reste du code AJAX peut être trouvé sur un précédent article publié sur ce blog, intitulé "Dé-raccourcisseur d’url". [...]

Ping by API de Untiny - 31 janvier 2010 à 15h14

Désolé, les commentaires sont fermés pour le moment.