2008-09-24 7 views
2

Aujourd'hui, je suis tombé sur un problème qui semble être un bug dans le Zend-Framework. Compte tenu de l'itinéraire suivant:Route-problème concernant Umlauts codés Url (en utilisant le Zend-framework)

<test> 
    <route>citytest/:city</route> 
    <defaults> 
     <controller>result</controller> 
     <action>test</action> 
    </defaults> 
    <reqs> 
     <city>.+</city> 
    </reqs> 
</test> 

et trois urls:

  • mysite.local/citytest/Berlin
  • mysite.local/citytest/Hamburg
  • mysite.local/citytest/M% FCnchen

La dernière URL ne correspond pas et donc le contrôleur correct n'est pas appelé. Quelqu'un a une idée pourquoi?

Fyi, où utilisent Zend Framework-1.0 (Oui, je sais que ce vieux mais je ne suis pas responsable de changer cela: - /)

Edit: D'après ce que je l'entends, nous allons passer à Zend 1.5.6 bientôt, mais je ne sais pas quand, donc un Patch serait génial.

Edit: Je l'ai dépisté jusqu'à la ligne suivante (Zend/Controller/routeur/Route.php: 170):

$regex = $this->_regexDelimiter . '^' . 
    $part['regex'] . '$' . 
    $this->_regexDelimiter . 'iu'; 

Si je change que pour

$this->_regexDelimiter . 'i'; 

il travaux. D'après ce que je comprends, l'u-modificateur est pour travailler avec des caractères asiatiques. Comme je ne les utilise pas, je vais bien avec ce patch pour savoir. Merci d'avoir lu.

+0

Vous êtes sking pour un patch? – Till

Répondre

1

Le problème est le suivant:

Utilisation du/modificateur de motif u empêche mots d'être mutilée mais PCRE saute des chaînes de caractères avec valeurs du code supérieur à 127. Par conséquent, \ w volonté ne correspond pas à un mot multi-octets (ascii non inférieur) à tous (mais ne renverra pas non plus des parties de ). De la page de manuel pcrepattern;

En mode UTF-8, les caractères avec des valeurs supérieures à 128 ne correspondent \ d, \ s, ou \ w, et correspondent toujours \ D, \ S, et \ W. Cela est vrai même lorsque le support de propriété de caractère Unicode est disponible .

De Handling UTF-8 with PHP. Par conséquent, si votre URL est codée ISO-8859-1 (mysite.local/citytest/M% FCnchen) ou encodée en UTF-8 (mysite.local/citytest/M% C3% BCnchen), l'expression rationnelle par défaut est 'win' t match.

J'ai également fait des expériences avec des trémas dans des URL dans Zend Framework et j'en suis arrivé à la conclusion que vous ne voudriez pas vraiment de trémas dans vos URLs. Le problème est que vous ne pouvez pas compter sur l'encodage utilisé par le navigateur pour l'URL. Firefox (avant 3.0) par exemple UTF-8 n'encode pas les URL entrées dans la zone de texte de l'adresse (si non spécifiée dans about: config) et IE a une case à cocher dans ses options pour choisir entre l'encodage normal et UTF-8 . Mais si vous cliquez sur des liens dans une page, les deux navigateurs utilisent l'URL dans l'encodage donné (UTF-8 sur une page UTF-8). Par conséquent, vous ne pouvez pas être sûr de l'encodage des URL envoyées à votre application - et la détection de l'encodage utilisé n'est pas si triviale à faire.

Il est peut-être préférable d'utiliser des paramètres translittérés dans vos URL (par exemple, modifier AÄ et ainsi de suite). Il y a un moyen vraiment simple à cela (je ne sais pas si cela fonctionne avec toutes les langues, mais je l'utilise avec des chaînes allemandes et il fonctionne très bien):

function createUrlFriendlyName($name) // $name must be an UTF-8 encoded string 
{ 
    $name=mb_convert_encoding(trim($name), 'HTML-ENTITIES', 'UTF-8'); 
    $name=preg_replace(
     array('/&szlig;/', '/&(..)lig;/', '/&([aouAOU])uml;/', '/&(.)[^;]*;/', '/\W/'), 
     array('ss', '$1', '$1e', '$1', '-'), 
     $name); 
    $name=preg_replace('/-{2,}/', '-', $name); 
    return trim($name, '-'); 
} 
1

Le modificateur u permet à l'expression rationnelle d'attendre une entrée utf-8. Cela suggère que ZF attend une entrée codée en utf-8, et non ISO-8859-1 (je ne connais pas trop ZF, donc je ne fais que deviner ici).

Si c'est le cas, vous devrez utf-8 encode le ü avant de l'utiliser dans une URL. Il deviendrait alors: mysite.local/citytest/M%C3%BCnchen

Notez que depuis le reste de votre application parle probablement ISO-8859-1 (qui est par défaut pour PHP < = 5), vous devrez décoder explicitement la variable avec utf8_decode, avant de pouvoir utilise le.

2

S'il vous plaît son travail parfait pour moi

/^[\p{L}-. ]*$/u 
  • ^ Début de la chaîne
  • [ ... ]* zéro ou plusieurs des éléments suivants:
  • \p{L} Unicode lette caractères r
  • traits
  • . périodes
  • espaces
  • $ Fin de la chaîne
  • /u Activer le mode Unicode dans PHP

Exemple:

$str= ‘Füße’; 
if (!preg_match(“/^[\p{L}-. ]*$/u”, $str)) 
{ 
    echo ‘error’; 
} 
else 
{ 
    echo “success”; 
} 
Questions connexes