Pregunta

Hoy me topé con un problema que parece ser un error en Zend-Framework.Dada la siguiente ruta:

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

y tres URL:

  • mysite.local/citytest/Berlín
  • mysite.local/citytest/Hamburgo
  • mysite.local/citytest/M%FCnchen

la última URL no coincide y, por lo tanto, no se llama al controlador correcto.¿Alguien tiene una idea de por qué?

Para tu información, ¿dónde estás usando Zend-Framework 1.0 (Sí, sé que es antiguo pero no estoy a cargo de cambiarlo :-/)

Editar:Por lo que he oído, pronto actualizaremos a Zend 1.5.6, pero no sé cuándo, por lo que un parche sería genial.

Editar:Lo rastreé hasta la siguiente línea (Zend/Controller/Router/Route.php:170):

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

Si cambio eso a

  $this->_regexDelimiter . 'i';

funciona.Por lo que tengo entendido, el modificador u es para trabajar con caracteres asiáticos.Como no los uso, me parece bien ese parche para saberlo.Gracias por leer.

¿Fue útil?

Solución

El problema es el siguiente:

El uso del modificador del patrón /u evita que las palabras se destrozaran, pero en su lugar, PCRE omita las cadenas de caracteres con valores de código superiores a 127.Por lo tanto, W no coincidirá con una palabra multibyte (ASCII no más baja) en absoluto (pero tampoco devolverá porciones de ella).Desde la página de manual de pcrepattern;

En el modo UTF-8, los caracteres con valores superiores a 128 nunca coinciden con d, s o w, y siempre coinciden d, s y w.Esto es cierto incluso cuando el soporte de propiedad de personaje Unicode está disponible.

De Manejando UTF-8 con PHP.Por lo tanto, en realidad es irrelevante si su URL está codificada en ISO-8859-1 (mysite.local/citytest/M%FCnchen) o UTF-8 (mysite.local/citytest/M%C3%BCnchen), la expresión regular predeterminada no lo hará. fósforo.

También hice experimentos con diéresis en URL en Zend Framework y llegué a la conclusión de que realmente no querrías diéresis en tus URL.El problema es que no puedes confiar en la codificación utilizada por el navegador para la URL.Firefox (anterior a 3.0), por ejemplo, no codifica UTF-8 las URL ingresadas en el cuadro de texto de la dirección (si no se especifica en about:config) e IE tiene una casilla de verificación dentro de sus opciones para elegir entre codificación normal y UTF-8 para sus URL. .Pero si hace clic en enlaces dentro de una página, ambos navegadores usan la URL en la codificación dada (UTF-8 en una página UTF-8).Por lo tanto, no puede estar seguro de en qué codificación se envían las URL a su aplicación, y detectar la codificación utilizada no es tan trivial.

Quizás sea mejor utilizar parámetros transliterados en sus URL (p. ej.cambie Ä a Ae y así sucesivamente).Hay una forma realmente sencilla de hacer esto (no sé si funciona con todos los idiomas, pero lo estoy usando con cadenas en alemán y funciona bastante 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, '-');
}

Otros consejos

Por favor me funciona perfecto

/^[\p{L}-. ]*$/u
  • ^ Inicio de la cuerda
  • [ ... ]* Cero o más de los siguientes:
  • \p{L} Caracteres de letras Unicode
  • guiones
  • . periodos
  • espacios
  • $ Fin de la cuerda
  • /u Habilitar el modo Unicode en PHP

EJEMPLO:

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

El modificador u hace que la expresión regular espere una entrada utf-8.Esto sugeriría que ZF espera una entrada codificada en utf-8, y no en ISO-8859-1 (no estoy muy familiarizado con ZF, así que solo estoy adivinando).

Si ese es el caso, tendrás que codificación utf-8 el ü antes de usarlo en una URL.Entonces pasaría a ser: mysite.local/citytest/M%C3%BCnchen

Tenga en cuenta que dado que el resto de su aplicación probablemente habla ISO-8859-1 (que es el valor predeterminado para PHP <= 5), tendrá que decodificar explícitamente la variable con utf8_decode, antes de poder usarlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top