Проблема с маршрутом относительно Umlauts в кодировке Url (с использованием Zend-framework) - PullRequest
2 голосов
/ 24 сентября 2008

Сегодня я наткнулся на проблему, которая кажется ошибкой в ​​Zend-Framework. Учитывая следующий маршрут:

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

и три URL:

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

последний URL не совпадает, и поэтому правильный контроллер не вызывается. Кто-нибудь понял, почему?

Fyi, где используется Zend-Framework 1.0 (Да, я знаю, что это древнее, но я не отвечаю за то, чтобы изменить это: - /)

Редактировать: Из того, что я слышал, мы скоро перейдем на Zend 1.5.6, но я не знаю, когда, так что патч будет отличным.

Редактировать: я отследил его до следующей строки (Zend / Controller / Router / Route.php: 170):

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

Если я изменю это на

  $this->_regexDelimiter . 'i';

это работает. Насколько я понимаю, u-модификатор предназначен для работы с азиатскими символами. Поскольку я ими не пользуюсь, я в порядке с этим патчем. Спасибо за чтение.

Ответы [ 3 ]

2 голосов
/ 23 июня 2011

Пожалуйста, его работа идеально подходит для меня

/^[\p{L}-. ]*$/u
  • ^ Начало строки
  • [ ... ]* Ноль или более из следующего:
  • \p{L} Буквы Unicode
  • тире
  • . периоды
  • пробелы
  • $ Конец строки
  • /u Включить режим Unicode в PHP
* 1 028 * Пример:
$str= ‘Füße’;
if (!preg_match(“/^[\p{L}-. ]*$/u”, $str))
{
    echo ‘error’;
}
else
{
    echo “success”;
}
1 голос
/ 27 сентября 2008

Проблема заключается в следующем:

Использование модификатора шаблона / u предотвращает слова изуродованы, но вместо PCRE пропускает строки символов с кодовые значения больше 127. Следовательно, \ w не будет соответствовать многобайтовое (не нижнее ascii) слово в все (но также не вернут части Это). Со страницы руководства pcrepattern;

В режиме UTF-8 символы со значениями больше 128 никогда не совпадают \ d, \ s, или \ w, и всегда совпадают с \ D, \ S и \ W. Это верно даже тогда, когда Unicode поддержка свойств персонажа имеется.

С Обработка UTF-8 с PHP . Поэтому это на самом деле не имеет значения, если ваш URL-адрес закодирован в формате ISO-8859-1 (mysite.local / citytest / M% FCnchen) или в кодировке UTF-8 (mysite.local / citytest / M% C3% BCnchen), регулярное выражение по умолчанию не будет матч.

Я также провел эксперименты с умлаутами в URL в Zend Framework и пришел к выводу, что вам не нужны умлауты в ваших URL. Проблема в том, что вы не можете полагаться на кодировку, используемую браузером для URL. Например, Firefox (до версии 3.0) не кодирует UTF-8 URL-адреса, введенные в текстовое поле адреса (если не указано в about: config), и IE имеет флажок в своих опциях для выбора между обычной и кодировкой UTF-8 для своих URL-адресов. , Но если вы нажимаете на ссылки на странице, оба браузера используют URL в заданной кодировке (UTF-8 на странице UTF-8). Поэтому вы не можете быть уверены, в какой кодировке URL-адреса отправляются вашему приложению - и обнаружение используемой кодировки не так просто.

Возможно, лучше использовать транслитерированные параметры в ваших URL (например, изменить Ä на Ae и т. Д.). Существует очень простой способ (я не знаю, работает ли это на всех языках, но я использую его с немецкими строками, и он работает довольно хорошо):

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 голос
/ 24 сентября 2008

Модификатор u заставляет регулярное выражение ожидать ввода utf-8. Это предполагает, что ZF ожидает кодированный ввод utf-8, а не ISO-8859-1 (я не слишком знаком с ZF, так что я просто догадываюсь здесь).

Если это так, вам придется utf-8 кодировать ü, прежде чем использовать его в URL. Тогда он станет: mysite.local/citytest/M%C3%BCnchen

Обратите внимание, что, поскольку остальная часть вашего приложения, вероятно, говорит по ISO-8859-1 (что по умолчанию для PHP <= 5), вам придется явно декодировать переменную с помощью <a href="http://www.php.net/utf8_decode" rel="nofollow noreferrer"> utf8_decode , прежде чем вы сможете использовать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...