PHP & MySQL

Générer des urls optimisées et lisibles

Le 27 octobre 2007 à 22:35 par chris

Ce n’est un secret pour personne, Google prend en compte les mots clés se trouvant dans les urls des pages web, aussi, une url contenant le titre de la page est plutôt bien vue.

Ensuite, c’est toujours plus sympa de savoir de quoi parle une page avant de cliquer sur son url.

Voici comment procéder pour exploiter des urls type “mapage/10-le-smashing-coding” au lieu de “mapage/?id=10

pour commencer , copier coller cette fonction dans dans la page PHP qui va générer l’url:

  1. function pre_url($texte) {$texte = html_entity_decode($texte);$tofind = utf8_decode( ‘ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËéèêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ’ );
  2. $replac = utf8_decode( ‘AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn’ );
  3. $texte_pre_pre_pre = trim(strtolower(strtr($texte,$tofind,$replac)));
  4. $texte_pre_pre = eregi_replace(‘[^a-zA-Z0-9_]’, ‘-’, $texte_pre_pre_pre);
  5. $texte_pre = eregi_replace(‘-+’, ‘-’, $texte_pre_pre);
  6. $texte_final = substr($texte_pre, ‘0′, ‘128′);
  7. $end = substr($texte_final, -1, 1);
  8. if ($end == "-") $texte_final = substr($texte_final, 0, -1);
  9. return $texte_final;
  10. }

Comme vous pouvez le constater, cette fonction va convertir un texte genre “à l’école” en “a-l-ecole”.

Il peut être nécessaire d’adapter cette fonction selon votre type d’encodage de caractères.

Maintenant, imaginons que vous publiez une liste d’articles, vous utiliserez une requête Mysql de ce genre:

  1. $req = mysql_query("SELECT id, titre FROM malist WHERE category = ‘$cat’ ");
  2. while($data = mysql_fetch_assoc($req))
  3. {
  4. echo ‘<li><a href="mapage/’. $data[‘id’] .‘-’. pre_url($data[‘titre’]).‘">’. $data[‘titre’] .‘</a></li>’;
  5. }

Bon ça c’est bien joli, mais ensuite, il faut lire les urls.

C’est pas compliqué avec la magie du .htaccess
dans un .htaccess se situant à la racine du site, vous placerez ces lignes:

  1. Options +FollowSymlinks
  2. RewriteEngine on
  3. RewriteRule ^mapage/([0-9]+)-(.*)$ mapage/index.php?id=$1 [L]

Et voilà, c’est magique, vos urls seront bien plus jolies

14 commentaires »

Gravatar

Commentaire de Damien

le 28 octobre 2007 à 0:24

Pas mal, il manque juste selon moi un test pour éviter d’avoir un séparateur - en fin d’url, c’est disgracieux ^^

(exemple, un titre avec un signe de ponctuation style “On m’a volé mon ipod !” donnerait avec cette fonction “on-m-a-vole-mon-ipod-”, le tiret final n’est pas utile.)

Gravatar

Commentaire de David

le 28 octobre 2007 à 1:26

Génial !! A part ce petit soucis qui n’en est pas un, cette astuce est vraiment géniale ! Merci beaucoup pour cette info, ce blog est vraiment une super idée ! Continuez !!

Gravatar

Commentaire de Tommy

le 28 octobre 2007 à 12:18

Il serait plus judicieux de retirer également les mots de moins de 3 lettres dans les urls car ils sont peu utile et si on les laisse, on peut arriver à des urls assez longues…

Gravatar

Commentaire de saian

le 28 octobre 2007 à 12:46

Jai une parse erreur à la ligne :
$texte_pre_pre = eregi_replace(‘[^a-zA-Z0-9_]’, ‘-’, $texte_pre_pre_pre);

Quand je remplace les ‘ par des ‘ j’en ai plus mais il me retourne aucun résultat.

Gravatar

Commentaire de chris

le 28 octobre 2007 à 12:54

@Damien, c’est mis à jour.

@Tommy: c’est une question de point de vue. Moi je préfère “roi-de-la-glisse” que “roi-glisse”

@saian: en fait, il faut mieux éviter le copier-coller, visiblement, wordpress a modifié les cotes à sa façon.

Gravatar

Commentaire de Antoine

le 28 octobre 2007 à 18:24

Pour éviter de faire trop souvent appel à la fonction, on peut aussi enregistrer le résultats dans la base à la manière des identifiants de Wordpress.
Dans ce cas on utilise la fonction uniquement lors de l’enregistrement de l’article. Ca permet de gagner un peu de temps lorsque l’on a beaucoup d’url à générer (style annuaire), on peut aussi avoir la main sur l’url rewritée et eventuellement faire des modifications.

Gravatar

Commentaire de chris

le 28 octobre 2007 à 18:45

@Antoine, tout à fait, mais cette remarque vaut pour toute les fonctions lourdes.

Mais ici, vous remarquerez que vous pouvez mettre à jour quasiment n’importe quel site avec cette technique, sans perte de liens puisque la page répondra toujours à son ancien URL.

Gravatar

Commentaire de Antoine

le 28 octobre 2007 à 19:02

@Chris, dans ce cas une petite redirection 301 en plus pour éviter le duplicata.

Gravatar

Commentaire de Boris

le 28 octobre 2007 à 19:07

Salut,

Pour le tiret de la fin comme ça c’est quand même plus simple ..

$texte_final = preg_replace(’/\-$/’,”,$texte_final);

PS1 : L’effet + les couleurs des commentaires piquent les yeux IMHO

PS2 : Tu devrais mettre sur ton blog un doctype transitional, la plupart des erreurs de validation disparaitraient (enfin on passerait de 16 à 6 erreurs pour cette page)

Gravatar

Commentaire de chris

le 28 octobre 2007 à 19:43

@boris: Bien vu le regex, je prend note.
“PS1″ chez moi, les couleurs sont agréable, j’y songerai pour la V2
“PS2″ Non, je corrigerai plutôt les erreurs, lorsque j’aurai le temps, mais j’ai réalisé ce thème sans connection internet.

Gravatar

Commentaire de Thomas

le 28 octobre 2007 à 19:54

Quelques remarques sur le code de la fonction :

#3 : $texte_pre_pre_pre… Pourquoi créer autant de variables temporaires ? Le fait de ne garder qu’une variable ($texte par exemple) permet d’en économiser 5 ;-)

#4 : eregi_replace est plus lent que preg_replace…

#6 substr() admet des valeurs numériques, donc sans apostrophes autour

#7-#8 : la création d’une variable $end est un peu inutile à mon sens, il suffit simplement de mettre la fonction substr() directement dans la condition : même résultat mais plus propre et plus rapide)

Sinon, 128 caractères de long, peut-être est-ce un peu trop pour un identifiant d’URL, non ? Google ne pénalise t-il pas les URLs trop longues ?

Voilà, j’espère que vous tiendrez compte de ces petites suggestions :-)

Bonne continuation,
Thomas

Gravatar

Commentaire de chris

le 28 octobre 2007 à 20:09

@Thomas. bien sur qu’on prend en compte les remarques, c’est tout l’intérêt d’avoir des commentaires ouvert.

En fait j’ai trouvé cette fonction il y a longtemps, je ne l’ai pas codé, ni optimisée et avec tes remarques, je vois effectivement qu’elle pourrait être optimisée.

Avec une petite optimisation on pourrait obtenir ceci:

function pre_url($texte) {
$texte = html_entity_decode($texte);
$tofind = utf8_decode( ‘ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËéèêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ’ );

$replac = utf8_decode( ‘AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn’ );

$texte = trim(strtolower(strtr($texte,$tofind,$replac)));

$texte = eregi_replace(’[^a-zA-Z0-9_]’, ‘-’, $texte);

$texte = eregi_replace(’-+’, ‘-’, $texte);

$texte = substr($texte, 0, 128);

$texte = preg_replace(’/\-$/’,”,$texte);

return $texte;

}

Gravatar

Commentaire de Boris

le 28 octobre 2007 à 20:10

Le problème c’est que le doctype strict est très limitant, par exemple tu ne peux pas mettre d’attribut href sur les anchors, ce qui peut être pénalisant, surtout si tu ne maîtrise pas tout le contenu (commentaires, etc …)

Mais c’est toi qui voit ;-)

Gravatar

Commentaire de Boris

le 28 octobre 2007 à 20:11

Euh, il fallait lire “d’attribut target” ;-)

Laisser un commentaire

Votre Nom

Votre E-mail (obligatoire mais ne sera pas publié)

Votre Site ou blog

Votre commentaire

Valid XHTML 1.0 Transitional