今天我偶然发现了一个问题,它似乎是 Zend-Framework 中的一个错误。给定以下路线:

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

和三个网址:

  • mysite.local/citytest/柏林
  • mysite.local/citytest/汉堡
  • mysite.local/citytest/M%FCnchen

最后一个 URL 不匹配,因此不会调用正确的控制器。有人知道为什么吗?

仅供参考,在哪里使用 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 修饰符用于处理亚洲字符。因为我不使用它们,所以我对那个补丁很满意。谢谢阅读。

有帮助吗?

解决方案

问题如下:

使用 /U模式修饰符可以防止单词被弄脏,而是PCRE跳过了代码值大于127的字符字符串。因此, w根本不匹配多键(非慢速ASCII)单词(但也不会返回其部分)。来自 pcrepattern 手册页;

在UTF-8模式下,值大于128的字符永远不匹配 d, s或 w,并且始终匹配 d, s和 w。即使有Unicode字符属性支持,也是如此。

使用 PHP 处理 UTF-8。因此,如果您的 URL 是 ISO-8859-1 编码 (mysite.local/citytest/M%FCnchen) 或 UTF-8 编码 (mysite.local/citytest/M%C3%BCnchen),则实际上无关紧要,默认正则表达式不会匹配。

我还在 Zend Framework 中的 URL 中对变音符号进行了实验,并得出结论:您实际上并不希望在 URL 中使用变音符号。问题是,您不能依赖浏览器对 URL 使用的编码。例如,Firefox(3.0 之前的版本)不会对地址文本框中输入的 URL 进行 UTF-8 编码(如果未在 about:config 中指定),而 IE 的选项中确实有一个复选框,可以在其 URL 的常规编码和 UTF-8 编码之间进行选择。但是,如果您单击页面内的链接,则两个浏览器都会使用给定编码(UTF-8 页面上的 UTF-8)的 URL。因此,您无法确定 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, '-');
}

其他提示

请它对我来说非常完美

/^[\p{L}-. ]*$/u
  • ^ 字符串的开头
  • [ ... ]* 以下零个或多个:
  • \p{L} Unicode 字母字符
  • 破折号
  • . 时期
  • 空间
  • $ 字符串结尾
  • /u 在 PHP 中启用 Unicode 模式

例子:

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

u 修饰符使正则表达式期望 utf-8 输入。这表明 ZF 需要 utf-8 编码输入,而不是 ISO-8859-1 (我对 ZF 不太熟悉,所以我只是在这里猜测)。

如果是这样的话,你就必须 utf-8编码ü 在 URL 中使用它之前。那么它就会变成: mysite.local/citytest/M%C3%BCnchen

请注意,由于应用程序的其余部分可能使用 ISO-8859-1(这是 PHP <= 5 的默认值),因此您必须使用显式解码变量 utf8_解码, ,然后才能使用它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top