[Script PHP] Fonctions pour créer un slug (SEO friendly URL)

WRInaute accro
Bonjour,

J'aimerais savoir ce que vous utilisez comme fonction dite de "slug": pour transformer un titre en URL.

Voici la fonction que j'utilise:
Code:
function slug($slug){
	$bad = array( 'Š','Ž','‘','ž','Ÿ','À','Á','Â','Ã','Ä','Å','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ñ',
	'Ò','Ó','Ô','Õ','Ö','Ø','Ù','Ú','Û','Ü','Ý','à','á','â','ã','ä','å','ç','è','é','ê',
	'ë','ì','í','î','ï','ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','ÿ',
	'Þ','þ','Ð','ð','ß','Œ','œ','Æ','æ','µ',
	'”',"'",'“','"',"\n","\r",'_','&',':','/');
	
	$good = array( 'S','Z','s','z','Y','A','A','A','A','A','A','C','E','E','E','E','I','I','I','I','N',
	'O','O','O','O','O','O','U','U','U','U','Y','a','a','a','a','a','a','c','e','e','e',
	'e','i','i','i','i','n','o','o','o','o','o','o','u','u','u','u','y','y',
	'TH','th','DH','dh','ss','OE','oe','AE','ae','u',
	'','-','','','','','-','','','');
	
	// replace strange characters with alphanumeric equivalents
	$slug = str_replace( $bad, $good, $slug );
	
	$slug = trim($slug);
	
	// remove any duplicate whitespace, and ensure all characters are alphanumeric
	$bad_reg = array('/\s+/','/[^A-Za-z0-9\-]/');
	$good_reg = array('-','');
	$slug = preg_replace($bad_reg, $good_reg, $slug);
	
	// and lowercase
	$slug = strtolower($slug);
	
	return $slug;
}
Mais ce la ne fonctionne pas bien pour des titres style:
- mon,super,titre (cela donne: monsupertitre, je voudrais: mon-super-titre)
- super...formidable (cela donne: superformidable)

Je me tourne vers vous afin de peut-être trouver une meilleure fonction.
 
WRInaute passionné
Hello,

moi j'utilise ça depuis des années :
Code:
    static public function rewrite( $chaine )
    {
        // remplace les caractères accentués par leur version non accentuée
        $id = strtr( $chaine,
                'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ',
                'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy' );

        // remplace les caractères non standards
        $id = preg_replace(
                array(
                    '`^[^A-Za-z0-9]+`',
                    '`[^A-Za-z0-9]+$`',
                    '`[^A-Za-z0-9]+`' ),
                array('','','-'),
                $id );

        return $id;
    }

Le soucis étant que la première chaine est encodée en "windows cp1252" ; si bien que ce code est difficilement modifiable sous une autre plateforme...

Sinon :
- mon,super,titre donne mon-super-titre
- super....formidable donne super-formidable
- "super titre !" donne super-titre
 
WRInaute impliqué
Code:
function format_url( $url, $type = '' ) {
    $url = preg_replace("`\[.*\]`U","",$url);
    $url = preg_replace('`&(amp;)?#?[a-z0-9]+;`i','-',$url);
    $url = htmlentities($url, ENT_NOQUOTES, 'ISO-8859-1');
    $url = preg_replace( "`&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig);`i","\\1", $url );
    $url = preg_replace( array("`[^a-z0-9]`i","`[-]+`") , "-", $url);
    $url = ( $url == "" ) ? $type : strtolower(trim($url, '-'));
    return $url;
}

La meilleure que j'ai trouvé :)
 
WRInaute impliqué
Celle où tu sens le meilleur feeling ? ^^

Au début j'en avais une autre différente dans le genre de la première postée mais je ne la trouvais vraiment pas "propre" (va savoir pourquoi). Puis je suis tombé sur celle-ci et elle m'a plus en m'offrant des choses encore mieux que l'autre (les - au lieu des _, la suppression des espace a la fin du titre quand y'avait " !") donc je l'ai adopté et puis le fait que ce soit celle utilisée par phpbbSEO pour ses mods de rewrite, cela m'a donné confiance.
 
Nouveau WRInaute
Bonjour,

Voici se que je me suis codé

Code:
function StringClean($Str){
	
	$Str = strtolower($Str);
	$Str = strtr($Str, 'àáâãäåòóôõöøèéêëçìíîïùúûüÿñ', 'aaaaaaooooooeeeeciiiiuuuuyn'); 

	# Ponctuation
	$Stop[] = '(';
	$Stop[] = ')';
	$Stop[] = '[';
	$Stop[] = ']';
	$Stop[] = '{';
	$Stop[] = '}';
	$Stop[] = '&';
	$Stop[] = '.';
	$Stop[] = ';';
	$Stop[] = ':';
	$Stop[] = ',';
	$Stop[] = '!';
	$Stop[] = '?';
	$Stop[] = '<';
	$Stop[] = '>';
	
	# Math
	$Stop[] = '+';
	$Stop[] = '-';
	$Stop[] = '*';
	$Stop[] = '/';
	$Stop[] = '°';
	$Stop[] = '%';
	$Stop[] = 'µ';
	$Stop[] = '§';
	
	# Diver
	$Stop[] = '_';
	$Stop[] = '#';
	$Stop[] = '~';
	$Stop[] = '|';
	$Stop[] = '^';
	$Stop[] = '@';
	$Stop[] = '¨';
	$Stop[] = '$';
	$Stop[] = '€';
	$Stop[] = '£';

	$Str = str_replace($Stop, ' ', $Str);

	# Remplacement espace multiple
	return ereg_replace(' +', '-', trim($Str));
}
 
WRInaute passionné
quand même je vous donne ma fonction :

Code:
//////////////////////////////////////////////////
// CREER LE LIEN POUR URL REWRITING //
/////////////////////////////////////////////////

function replace_char($theString){										
	$theString = stripslashes(strtolower($theString));				
	
// Remplacement des a accentues.									
	$a_accent  = "[&agrave;|&acirc;|&Agrave;|&Acirc;";					
	$a_accent .= "|À|Á|Â|Ã|Ä|Å|Æ|à|á|â|ã|ä|å|æ]";						
	$theString = preg_replace($a_accent,"a",$theString);				
	
//remplacement des cedilles											
	$c_cedille = "[&ccedil;|&Ccedil;|ç]";								
	$theString = preg_replace($c_cedille,"c",$theString);				
	
//remplacement des e accentues										
	$e_accent  = "[&eacute;|&egrave;|&euml;|&ecirc;|&Eacute;|&Egrave;|";
	$e_accent .= "&Euml;|&Ecirc;|È|Ê|Ë|É|è|é|ê|ë]";						
	$theString = preg_replace($e_accent,"e",$theString);				
	
//remplacement des i accentues										
	$i_accent = "[&iuml;|&icirc;|&Iuml;|&Icirc;|Ì|Í|Î|Ï|ì|í|î|ï]";		
	$theString = preg_replace($i_accent,"i",$theString);				
	
//remplacement des o accentues										
	$o_accent = "[&ocirc;|&Ocirc;|Ò|Ó|Ô|Õ|Ö|ö|õ|ô|ó|ò|ð|Ø|ø]";			
	$theString = preg_replace($o_accent,"o",$theString);				
	
//remplacement des u accentues										
	$u_accent =  "[&ugrave;|&ucirc;|&Ugrave;|&Ucirc;|Ù|Ú|Û|Ü|ü|û|ú|ù]";	
	$theString = preg_replace($u_accent,"u",$theString);				
	
//remplacement des espaces											
	$any_space = "[ |/]";												
	$theString = preg_replace($any_space,"-",$theString);				
	
//remplacement des quote											
	$any_quote = "[\?|'|\"]";											
	$theString = preg_replace($any_quote,"-",$theString);				
	/
/remplacement des paranthèses											
	$any_quote = "[\(|\)]";											
	$theString = preg_replace($any_quote,"-",$theString);
	
//remplacement des plus											
	$any_quote = "[\+]";											
	$theString = preg_replace($any_quote,"-",$theString);
				
//remplacement des double tirets
	$any_quote = "[-----|----|---|--]";											
	$theString = preg_replace($any_quote,"-",$theString);

	return ($theString);												
}

enfin je suis conscient que c'est pas optimisé du tout ... car ça ne gère pas du tout les caractères spéciaux
 
WRInaute passionné
darkjukka a dit:
Celle où tu sens le meilleur feeling ? ^^

Au début j'en avais une autre différente dans le genre de la première postée mais je ne la trouvais vraiment pas "propre" (va savoir pourquoi). Puis je suis tombé sur celle-ci et elle m'a plus en m'offrant des choses encore mieux que l'autre (les - au lieu des _, la suppression des espace a la fin du titre quand y'avait " !") donc je l'ai adopté et puis le fait que ce soit celle utilisée par phpbbSEO pour ses mods de rewrite, cela m'a donné confiance.

salut,

juste une question : est-ce que ta méthode gère les caractères spéciaux suivants (ou autres) :

# Math
$Stop[] = '+';
$Stop[] = '-';
$Stop[] = '*';
$Stop[] = '/';
$Stop[] = '°';
$Stop[] = '%';
$Stop[] = 'µ';
$Stop[] = '§';

# Diver
$Stop[] = '_';
$Stop[] = '#';
$Stop[] = '~';
$Stop[] = '|';
$Stop[] = '^';
$Stop[] = '@';
$Stop[] = '¨';
$Stop[] = '$';
$Stop[] = '€';
$Stop[] = '£';

???
 
WRInaute impliqué
La chaine :
Code:
+-*/°%µ§_#~|^@¨$€£
me retourne
Code:
deg-micro-sect-uml-pound

Mais honnêtement, tu pense avoir ce genre de caractères dans un titre ou une url ?
 
WRInaute accro
J'ai fais des test sur une cinquantaine de titres de ma BDD (petites annonces)

Je viens de tester la fonction de darkjukka, c'est la plus courte :D

Mais un titre comme celui ci:
Informatique & Internet
deviens:
informatique-amp-internet

Avec la fonction de rudddy une phrase qui termine par ")" contient un tiret en trop à la fin.

Au final je teste la fonction de Bool, et c'est celle qui à l'air de mieux fonctionner. (je rajouterais juste un strtolower() en plus)
 
WRInaute passionné
spout a dit:
J'ai fais des test sur une cinquantaine de titres de ma BDD (petites annonces)

Je viens de tester la fonction de darkjukka, c'est la plus courte :D

Mais un titre comme celui ci:
Informatique & Internet
deviens:
informatique-amp-internet

pourquoi ne pas modifier si le seul problème est le & ???

spout a dit:
Avec la fonction de rudddy une phrase qui termine par ")" contient un tiret en trop à la fin.

exact c'est un de mes soucis principaux : comment y remédier ?

spout a dit:
Au final je teste la fonction de Bool, et c'est celle qui à l'air de mieux fonctionner. (je rajouterais juste un strtolower() en plus)

donc le vainqueur est ?
 
WRInaute impliqué
rudddy a dit:
oui : par exemple :

100% des gagnants on tenté leur chance !
Certes mais tu veux retrouver le % dans l'url ou pas ? A mon avis il ne vaudrait mieux pas l'inclure et donc là cela irait.

spout a dit:
Avec le "&" ça risque d'être plus fréquent
Là oui, à mon avis la modif à faire ne doit pas être compliqué
 
WRInaute passionné
Voilà la mienne

Code:
function ur($s) 
	{ 
	$avec_acc = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ' ; 
	$sans_acc = 'AAAAAAACEEEEIIIIDNOOOOOOUUUUYaaaaaaaceeeeiiiionoooooouuuuyy' ; 
	$s=stripslashes(html_entity_decode(strtr($s, $avec_acc, $sans_acc)));
	$s=eregi_replace("[^0-9a-z]+"," ",$s);
	return urlencode(strtolower(eregi_replace("[\ ]+","-",trim($s))));
	}

Si ça peut servir...
 
WRInaute accro
jeroen a dit:
Voilà la mienne

Code:
function ur($s) 
	{ 
	$avec_acc = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ' ; 
	$sans_acc = 'AAAAAAACEEEEIIIIDNOOOOOOUUUUYaaaaaaaceeeeiiiionoooooouuuuyy' ; 
	$s=stripslashes(html_entity_decode(strtr($s, $avec_acc, $sans_acc)));
	$s=eregi_replace("[^0-9a-z]+"," ",$s);
	return urlencode(strtolower(eregi_replace("[\ ]+","-",trim($s))));
	}

Si ça peut servir...

Même résultat (+strtolower) que celle de Bool. Mais preg_ est plus bcp rapide que eregi_
 
WRInaute accro
Pour la fonction de magic corp.: Si on l'appelle plusieurs fois, ça met un warning already defined.

Il faut donc rajouter un if(!defined())
Ce qui deviens:
Code:
function convert_for_uri($text) {
  // Définition du séparateur
  if(!defined("SEPARATOR"))
  define("SEPARATOR", "-");

  $tofind = "àáâãäåòóôõöøèéêëçìíîïùúûüÿñ"; // Lettre accentuées
  $replac = "aaaaaaooooooeeeeciiiiuuuuyn"; // Equivalant non accentué

  // Mise en minuscule + suppression des lettres accentuées par leur équivalant non accentué
  $text = strtr(strtolower($text),$tofind,$replac);

  // Remplacement de caractère non alphanumérique par un séparateur
  $text = ereg_replace("[^a-z0-9]", SEPARATOR, $text);

  // Suppression des doubles séparateurs
  while (strstr($text, SEPARATOR . SEPARATOR))
    $text = str_replace(SEPARATOR . SEPARATOR, SEPARATOR, $text);

  // Retour avec suppression d’un possible séparateur en fin de chaîne
  return(ereg_replace(SEPARATOR . "$", "", $text));
}

ou ne pas utiliser de constante et utiliser une simple variable $separateur

Finalement c'est la fonction de Bool que j'ai choisi (preg vs ereg)
 
Discussions similaires
Haut