2010-10-21 26 views
1

Je suis en train de créer un coffre-fort multibyte title => convertisseur de chaîne url, mais j'ai rencontré le problème de ne pas savoir comment autoriser les caractères légaux asiatiques (et autres) dans l'URL lors de la suppression des autres. C'est la fonction définie pour le moment.Multibyte Safe Url conversion de titre en PHP

public static function convertAccentedCharacters($string) 
{        
    $table = array(
      'Œ'=>'CE', 'œ'=>'ce', '¥'=>'Y', 'Ÿ'=>'Y', 'µ'=>'u', 'ü'=>'u', 
      'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c', 
      'À'=>'A', 'Á'=>'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', 'Þ'=>'B', 'ß'=>'Ss', 
      'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 
      'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 
      'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 
      'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', 
     ); 

    return str_replace(array_keys($table), array_values($table), $string); 
} 

public static function convertStringToSafeCharacters($string) 
{     
    $string = self::convertAccentedCharacters($string); 
    if (function_exists('mb_convert_encoding') === true) 
    { 
     $string = mb_convert_encoding($string, 'UTF-8', 'auto'); 
    } 
    else if(function_exists('iconv') === true && ($iconvstr = @iconv('', 'UTF-8', $string)) !== false) 
    { 
     $string = $iconvstr; 
    } 
    else 
    { 
     $string = utf8_decode($string); 
    } 
    return strip_tags(trim($string)); 
} 

public static function convertToUrlsafe($string, $options=array()) 
{  
    if(isset($options['separator']) === false || $options['separator'] === false) 
    { 
     global $_SITE; 
     if(strpos($_SITE->urlsafe_format, 'underscore') !== false) 
     { 
      $options['separator'] = '_'; 
     } 
     else 
     { 
      $options['separator'] = '-'; 
     } 
    } 
    if(isset($options['case']) === false || $options['case'] === false) 
    { 
     global $_SITE; 
     $format = substr($_SITE->urlsafe_format, 0, 5); 
     if($format === 'lower') 
     { 
      $options['case'] = 'lower'; 
     } 
     else if($format === 'upper') 
     { 
      $options['case'] = 'upper'; 
     } 
     else 
     { 
      $options['case'] = 'mixed'; 
     } 
    } 

    $string = self::convertStringToSafeCharacters($string); 

    $separator_in_use = $options['separator']; 
    $separtor_convert = $options['separator'] == '-' ? '_' : '-'; 
    $preg_changes = array(
//    convert other seperators into the seperator being used 
     '/\\'.$separtor_convert.'/i'   => $separator_in_use, 
//    remove any none legal chars 
     '/[^\-\_a-zA-Z0-9&\s]/i'    => '', 
     '/\&\#\d+?\;/'       => '', 
     '/\&\S+?\;/'       => '', 
//    replace spaces with separator 
     '/\s+/'         => $separator_in_use, 
//    replace amersands with and 
     '/\&/'         => 'and', 
//    now finally remove any last chars 
     '/[^A-Za-z0-9\/'.$separator_in_use.']/' => '', 
//    remove any double paddinging separators, ie ---- 
     '/'.$separator_in_use.'+/'    => $separator_in_use, 
//    remove separator padding from start and end of string 
     '/'.$separator_in_use.'$/'    => '', 
     '/^'.$separator_in_use.'/'    => '' 
    ); 
    $string = preg_replace(array_keys($preg_changes), array_values($preg_changes), $string); 
    switch($options['case']) 
    { 
     case 'lower' : 
      $string = strtolower($string); 
      break; 
     case 'upper' : 
      $string = strtoupper($string); 
      break; 
     case 'mixed' : 
      // do nothing 
    } 
    return $string; 
} 

S'il vous plaît garder à l'esprit qu'il ya certaines fonctionnalités liées à la CMS là-bas et que les fonctions sont en fait partie d'une classe. Le principal appel de fonction serait

convertToUrlsafe($string); 

Et je suis sûr que le problème est lié à l'expression rationnelle remplace dans cette fonction elle-même, mais je ne suis pas tout à fait sûr ce qu'il faut changer sans casser des fonctionnalités existantes.

Je veux être en mesure de prendre les titres suivants et de les faire retourner les titres sécurisés.

"Le tout premier blog!" => "La-Très-première Blog"

"ス ー ザ ン は 本 日, グ ラ ス ゴ ー の ベ ラ ヒ ュ ー ス ト ン · パ ー ク で ロ ー マ 法王 の" (aucune idée de ce que cela dit), mais il doit être converti en urlsafe et au moment ça renvoie juste une chaîne vide.

Répondre

1

Il n'y a pas de caractères "légaux asiatiques" dans les URL: les URL peuvent contenir uniquement des caractères ASCII.

Les caractères occidentaux que vous pouvez normaliser en utilisant votre méthode (ou par exemple iconv(); here est une autre alternative). Pour tout le reste, utilisez le codage en pourcentage (c'est-à-dire urlencode). Les navigateurs modernes afficheront automatiquement les caractères appropriés, le cas échéant.

Contexte: Unicode characters in URLs

+0

Hmm ok. Je pense que j'étais confus parce que j'ai vérifié les pages wiki asiatiques et ils ont les caractères corrects, mais en lisant vos autres messages il semble que c'est juste le navigateur décodant le format encodé url. Ma prochaine question serait de savoir comment ne pas détecter de caractères latins dans le texte. – buggedcom

+0

@buggedcom vérifier les liens dans la réponse que je lie à, une réponse fonctionne avec une table de remplacement; celui ci-dessous avec le paquet PECL 'Normalizer'. Les deux devraient fonctionner –

+0

@Pekka. Je pense que vous avez mal compris. Je veux détecter s'il y a un caractère non latin dans le texte, c.-à-d. "ラ" et s'il y a alors un ensemble différent de fonctions de traitement à travers la chaîne par rapport à une chaîne avec seulement des caractères latins. Je pensais que strlen() vs mb_strlen() peut fonctionner mais il ne le fait pas, il renvoie le même nombre de caractères pour l'exemple de chaîne ci-dessus. – buggedcom