Problema di rotta relativo agli Umlaut con codifica Url (usando il framework Zend)

StackOverflow https://stackoverflow.com/questions/127389

  •  02-07-2019
  •  | 
  •  

Domanda

Oggi mi sono imbattuto in un problema che sembra essere un bug nello Zend-Framework. Dato il seguente percorso:

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

e tre URL:

  • mysite.local / citytest / Berlino
  • mysite.local / citytest / Amburgo
  • mysite.local / citytest / M% FCnchen

l'ultimo URL non corrisponde e pertanto non viene chiamato il controller corretto. Qualcuno ha avuto un'idea del perché?

Fyi, dove sto usando Zend-Framework 1.0 (Sì, lo so che è antico ma non ho il compito di cambiarlo: - /)

Modifica: da quello che ho sentito, presto aggiorneremo a Zend 1.5.6, ma non so quando, quindi una patch sarebbe fantastica.

Modifica: l'ho rintracciato fino alla seguente riga (Zend / Controller / Router / Route.php: 170):

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

Se lo cambio in

  $this->_regexDelimiter . 'i';

funziona. Da quello che ho capito, il modificatore u è per lavorare con personaggi asiatici. Dato che non li uso, sto bene con quella patch per sapere. Grazie per aver letto.

È stato utile?

Soluzione

Il problema è il seguente:

  

L'uso del modificatore del modello / u impedisce   parole dall'essere mutilato ma invece   PCRE salta stringhe di caratteri con   valori di codice maggiori di 127.   Pertanto, \ w non corrisponderà a   parola multibyte (ascii non inferiore) a   all (ma ha anche vinto & # 8217; t restituisce porzioni di   esso). Dalla pagina man pcrepattern;

     

In modalità UTF-8, caratteri con valori   maggiore di 128 non corrisponde mai a \ d, \ s,   o \ w e corrisponde sempre a \ D, \ S e   \ W. Questo è vero anche quando Unicode   il supporto della proprietà del personaggio è   disponibili.

Da Gestione di UTF-8 con PHP . Pertanto è in realtà irrilevante se il tuo URL è codificato ISO-8859-1 (mysite.local / citytest / M% FCnchen) o UTF-8 codificato (mysite.local / citytest / M% C3% BCnchen), il regex predefinito non lo farà incontro.

Ho anche fatto esperimenti con le umlaut negli URL in Zend Framework e sono giunto alla conclusione che non vorresti davvero le umlaut nei tuoi URL. Il problema è che non puoi fare affidamento sulla codifica utilizzata dal browser per l'URL. Firefox (precedente alla 3.0) ad esempio UTF-8 non codifica gli URL immessi nella casella di testo dell'indirizzo (se non specificato in about: config) e IE ha una casella di controllo tra le sue opzioni per scegliere tra la codifica regolare e UTF-8 per i suoi URL . Ma se si fa clic sui collegamenti all'interno di una pagina, entrambi i browser utilizzano l'URL nella codifica specificata (UTF-8 su una pagina UTF-8). Pertanto, non puoi essere sicuro di quale codifica gli URL vengano inviati alla tua applicazione e rilevare la codifica utilizzata non è così banale da fare.

Forse è meglio usare i parametri traslitterati nei tuoi URL (es. modifica & # 196; in Ae e così via). C'è un modo davvero semplice per farlo (non so se funziona con tutte le lingue ma lo sto usando con stringhe tedesche e funziona abbastanza bene):

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, '-');
}

Altri suggerimenti

Per favore, funziona perfettamente per me

/^[\p{L}-. ]*$/u
  • ^ Inizio della stringa
  • [ ... ]* Zero o più dei seguenti:
  • \p{L} Caratteri lettera Unicode
  • trattini
  • . punti
  • spazi
  • $ Fine della stringa
  • /u Abilita la modalità Unicode in PHP

Esempio:

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

Il modificatore u fa sì che regexp si aspetti un input utf-8. Questo suggerirebbe che ZF prevede input codificato utf-8 e non ISO-8859-1 (non ho troppa familiarità con ZF, quindi sto solo indovinando qui).

In tal caso, dovrai codifica utf-8 il ü prima usandolo in un URL. Diventerebbe quindi: mysite.local/citytest/M%C3%BCnchen

Nota che poiché il resto della tua applicazione probabilmente parla ISO-8859-1 (che è l'impostazione predefinita per PHP < = 5), dovrai decodificare esplicitamente la variabile con utf8_decode , prima di poterlo utilizzare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top