Catégories

Articles récents


« | Retour | »

Une URL raccourcie sur votre domaine … pourquoi pas vous ?

Ecrit par Nicolas Frey le 21 août 2008

Il existe beaucoup de site pour faire des raccourcies URL mais pourquoi ne pas le faire sur votre propre domaine ?

Le développement est relativement simple, il suffit d’un serveur acceptant le PHP, d’une base de données et si possible la redirection d’url activé (mod_rewrite sous Apache). Le développement tient dans un script et un fichier .htaccess pour la redirection des URL.

La base de données contient une table avec un identifiant unique qui représente la clé d’accès et l’URL du lien sur lequel on veut rediriger.

1
2
3
4
5
CREATE TABLE `tinyurl` (
  `hash` varchar(16) NOT NULL,
  `url` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`hash`)
);

Le script PHP est loin d’être du code objet ou encore utiliser Zend Framework, mais pour un petit outil du genre un bon vieux code en procédural devrait faire l’affaire. Le script n’est pas très complexe. On a une partie pour afficher le formulaire, une fonction pour la création du hash, l’enregistrement dans la base de données et une fonction pour rechercher l’URL associé au hash.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
<?php
 
// Fichier qui contient les paramètres de connexion.
require_once('config.php'); 
 
/**
 * Connexion à la base de donnée
 */
$conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
        or die("Impossible de se connecter");
$db = mysql_select_db(DB_NAME, $conn) or die(mysql_error());
$table = "tinyurl";
define('HASHSIZE', '5'); // Taille du hash
 
/**
 * Recherche par rapport au hash passé en paramètre
 * et redirection sur l'URL.
 */
function renvoyer($hash) {
   global $table;
 
   if(is_hash($hash)) {
 
     $req = "SELECT * FROM $table WHERE hash = '$hash';";
     $res = mysql_query($req) or die("Query failed");
 
     if (mysql_num_rows($res) == 0) {
       print "Aucun id associé";
       return;
     }
     else {
       header("Location: " . mysql_result($res, 0, "url"), true);
       return;
     }
}
 
/**
 * Enregistrement de l'url avant son identifiant.
 */
function enregistrer( $url ) {
   global $table;
 
   if( !is_url($url) ) {
      print <<<HTML
                 <span class="error">
                    <i>{$url}</i> n'est pas une url valide
                 </span>
HTML;
 
      return;
   }
 
   // Test si l'url existe déjà et retourne le hash correspondant.
   // Évite les doublons inutiles.
   $req = "SELECT hash FROM $table WHERE url= '$url';";
   $res = mysql_query($req) or die("Query failed");
 
   // L'url existe déjà dans la base de données
   if ( mysql_num_rows($res) == 1 ) {
      $hash = mysql_result($res, 0, "hash");
 
      // A modifier en fonction de votre .htaccess et
      // des redirections d'url
      $adresse = "http://votredomain/" . $hash;
      print <<<HTML
		<span class="info">
                   Voici votre URL r&amp;eacute;duite :
                </span>
 
{$adresse}
 
HTML;
 
   }
 
   // L'url n'existe pas encore
   else {
 
      // Recherche un identifiant valide
      $ok = false; $count = 0;
      while (!$ok) {
 
         // Génération d'un hash
	 $hash = generateHash(HASHSIZE);
 
	 // Test si le hash n'existe pas déjà dans la base de données
  	 $req = "SELECT hash FROM $table WHERE hash= '$hash';";
	 $res = mysql_query($req) or die("Query failed");
 
         // Aucun résultat le hash est donc dispo
         if ( mysql_num_rows($res) == 0 ) $ok = true;
 
         // Nombre de tentative dépassée on arrête.
         if ( ++$count >= 10 ) break;
      }
 
      // Insertion de l'url dans la base de données
      $req = "INSERT INTO $table (hash, url) VALUES ('$hash', '$url');";
 
      // Insertion ok
      if (mysql_query($req)) {
         $adresse = "http://nfrey.com/" . $hash;
	 print <<<HTML
	  	   <span class="info">
                       Voici votre URL r&amp;eacute;duite :
                   </span>
 
{$adresse}
 
HTML;
      }
 
      // Erreur d'insertion
      else {
         print <<<HTML
		   <span class="error">
                      Une erreur s'est produite.
                   </span>
HTML;
      }
   }
}
 
/**
 * Vérification de l'url
 * La regex doit être grandement améliorée pour prendre en compte
 * tous les types d'url possible.
 * ex: protocole://sdo.domain.ext:port/dossier/file?param&amp;autres#ancre
 */
function is_url($url) {
   $motif_url=("^^(http|ftp|https)://([a-zA-Z0-9-]+.)?([a-zA-Z0-9-]+.)
               ?[a-zA-Z0-9-]+.[a-zA-Z]{2,4}(:[0-9]+)?(/[a-zA-Z0-9-]*)
               ?(.[a-zA-Z0-9]{1,4})?$");
   if (!ereg($motif_url, $url))
      return false;
   else
      return true;
}
 
/**
 * Génération d'un identifiant celui ci contient
 * des caractères alpha-numériques.
 * On lui passe en paramètre la taille que devra avoir l'identifiant
 */
function generateHash( $length ) {
 
   $hash = "";
 
   // Caractères possibles
   $possible = "0123456789abcdefghijklmnopqrstuvwxyz
                ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
 
   // Compteur pour la taille du hash
   $i = 0; 
 
   // ajoute un caractère aléatoirement au hash jusqu'à sa taille max
   while ( $i < $length ) {
      // Trouve un caractère de façon aléatoire dans la liste
      // des caractères possibles
      $char = substr( $possible, mt_rand(0, strlen($possible)-1), 1 );
 
      // Ne pas reprendre ce caractère s'il est déjà dans le hash
      if ( !strstr($hash, $char) ) {
         $hash .= $char;
	 $i++;
      }
   }
 
   // retour du résultat !
   return $hash;
}
 
/**
 * Vérification du hash
 * Doit contenir x caractères alpha numérique
 */
function is_hash($hash) {
   $motif_hash=("^([0-9A-Za-z]{" . HASHSIZE . "})$");
   if (!ereg( $motif_hash, $hash ))
      return false;
   else
      return true;
}
 
/**
 * Fonction d'affichage
 */
function affichage() {
 
   // Un id est passé en paramètre, on appel la fonction renvoyer
   if ( (isset($_REQUEST['id']) && !empty($_REQUEST['id']) ) ) {
      renvoyer($_REQUEST['id']);
   }
 
   // Retour du formulaire on créé une url, appel
   // de la fonction enregistrer
   else if ( (isset($_REQUEST['creer'])
              && $_REQUEST['creer'] == 'oui')
              && (isset($_REQUEST['url'])
              && !empty($_REQUEST['url']) ) ) {
      enregistrer($_REQUEST['url']);
   }
 
   // Affichage du formulaire pour la création de l'url
   else {
      echo <<<HTML
<form action="{$_SERVER['PHP_SELF']}" method="POST">
<input type="hidden" name="creer" value="oui" />
	  URL:
<input type="text" name="url" value="http://" />
<input type="submit" name="action" value="R&amp;eacute;duire" />
	</form>
 
HTML;
  	}
}
 
?>
 
<html>
   <head>
      <title>TinyURL</title>
   </head>
   <body>
      <?php affichage(); ?>
   </body>
</html>

Le hash sert donc à récupérer l’URL dans la base. L’URL récupérée depuis la base de donnée modifie aussitôt la page visualisée par l’utilisation de la fonction header().
Pour parfaire la chose, il faudrait créer un fichier .htaccess renvoyant les URL du type http://domaine/%hash% vers http://domaine/dossier/url.php?id=%hash% ….

Voici un exemple d’un fichier .htaccess

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Tester si le module apache existe
<IfModule mod_rewrite.c>
 
   # démarre la réécriture d'url
   RewriteEngine On
 
   # Redirection http://mondomaine/tinyurl sur le script php
   # (créé un petit lien)
   RewriteRule tinyurl$ /url/url.php
 
   # Redirection http://mondomaine/tinyurl/%hash% sur le script
   # avec le paramètre id
   RewriteRule tinyurl/([a-ZA-Z0-9]+)$ /url/url.php?id=$1 [L]
</IfModule>

Vous avez maintenant de quoi faire vos URL courtes sur votre site perso. Mon script est très légèrement différent et adapté pour être intégré dans WordPress vous pouvez le tester ici :

Si vous avez des remarques ou questions, je reste joinable. Vous trouverez mes coordonnées sur la page « à propos« .

Sujets: Développement, Internet 1 commentaire »

Une réponse pour “Une URL raccourcie sur votre domaine … pourquoi pas vous ?”

  1. Rachat secret dit:
    10 février 2010 à 3:42

    Bonjour, je vous félicite pour cet excellent article.

    J’ai testé, ça marche.

    Bonne continuation. Cordialement

Commentaires