Route-problema em relação Umlauts Url codificados (usando o Zend-quadro)
-
02-07-2019 - |
Pergunta
Hoje eu tropecei sobre um problema que parece ser um bug no Zend-Quadro. Dada a seguinte rota:
<test>
<route>citytest/:city</route>
<defaults>
<controller>result</controller>
<action>test</action>
</defaults>
<reqs>
<city>.+</city>
</reqs>
</test>
e três URLs:
- mysite.local / citytest / Berlin
- mysite.local / citytest / Hamburg
- mysite.local / citytest / M% FCnchen
o último Url não corresponder e, assim, o controlador correto não é chamado. Alguém tem uma pista porquê?
FYI, onde estão usando Zend Framework 1.0-(Sim, eu sei que é antiga, mas eu não sou responsável para mudar isso: - /)
Edit:. Pelo que ouvi, vamos atualizar para Zend 1.5.6 em breve, mas eu não sei quando, assim que um patch seria ótimo
Editar: Eu rastrearam a seguinte linha (Zend / Controller / Router / Route.php: 170):
$regex = $this->_regexDelimiter . '^' .
$part['regex'] . '$' .
$this->_regexDelimiter . 'iu';
Se eu mudar isso para
$this->_regexDelimiter . 'i';
ele funciona. Pelo que eu entendo, a u-modificador é para trabalhar com caracteres asiáticos. Como eu não usá-los, eu estou bem com isso patch para saber. Obrigado pela leitura.
Solução
O problema é o seguinte:
Usando os u impede / padrão modificadoras palavras de serem embaralhadas mas em vez disso PCRE ignora sequências de caracteres com código de valores superiores a 127. Portanto, \ w não irá corresponder a vários bytes (ASCII não-inferior) na palavra tudo (mas também não vai voltar porções de isto). A partir da página homem pcrepattern;
No modo UTF-8, caracteres com valores maior do que 128 nunca correspondem \ d, \ s, ou \ w, e sempre corresponder \ D \ S, e \W. Isso é verdade mesmo quando Unicode Apoio à Propriedade personagem é disponíveis.
A partir Handling UTF-8 com PHP . Portanto, é realmente irrelevante se o seu URL é ISO-8859-1 codificado (mysite.local / citytest / M% FCnchen) ou UTF-8 codificado (mysite.local / citytest / M% C3% BCnchen), a regex padrão não vai Combine.
Também fiz experimentos com tremas em URLs em Zend Framework e chegou à conclusão de que você realmente não quer tremas em suas URLs. O problema é que você não pode contar com a codificação usada pelo navegador para o URL. URLs Firefox (antes da 3.0), por exemplo, não UTF-8 codificar entrou na caixa de texto endereço (se não especificado no about: config) e IE tem uma caixa de seleção dentro de suas opções para escolher entre codificação regular e UTF-8 para suas URLs . Mas se você clicar em links dentro de uma página ambos os navegadores usar a URL na codificação dada (UTF-8 em uma página UTF-8). Portanto, você não pode ter certeza em que codificar os URLs são enviados para sua aplicação -. E detectar a codificação utilizada não é tão trivial para fazer
Talvez seja melhor usar parâmetros transliterado em suas URLs (por exemplo, alterar um para Ae e assim por diante). Há uma maneira muito simples para isso (eu não sei se isso funciona com qualquer língua, mas eu estou usando-o com cordas alemães e ele funciona muito bem):
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('/ß/', '/&(..)lig;/', '/&([aouAOU])uml;/', '/&(.)[^;]*;/', '/\W/'),
array('ss', '$1', '$1e', '$1', '-'),
$name);
$name=preg_replace('/-{2,}/', '-', $name);
return trim($name, '-');
}
Outras dicas
Por favor, seu perfeito trabalho para me
/^[\p{L}-. ]*$/u
-
^
início da string -
[ ... ]*
Zero ou mais dos seguintes: - caracteres Unicode
\p{L}
carta ??li> -
–
traços - períodos
.
- espaços
-
$
final da string -
/u
Ative o modo Unicode no PHP
Exemplo:
$str= ‘Füße’;
if (!preg_match(“/^[\p{L}-. ]*$/u”, $str))
{
echo ‘error’;
}
else
{
echo “success”;
}
O u modificador faz com que o regexp esperar utf-8 entrada. Isto sugeriria que ZF espera utf-8 entrada codificada, e não ISO-8859-1 (eu não estou muito familiarizado com ZF, por isso estou apenas supondo aqui).
Se for esse o caso, você terá que utf-8 codificar o ü
antes de usá-lo em um URL. Seria, então, tornar-se: mysite.local/citytest/M%C3%BCnchen
Note que, desde o resto da sua aplicação provavelmente fala ISO-8859-1 (que é padrão para PHP <= 5), você terá que decodificar explicitamente a variável com utf8_decode , antes que você possa usá-lo.