今天我偶然发现了一个似乎是Zend-Framework中的错误的问题。鉴于以下路线:
<test>
<route>citytest/:city</route>
<defaults>
<controller>result</controller>
<action>test</action>
</defaults>
<reqs>
<city>.+</city>
</reqs>
</test>
和三个网址:
最后一个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-modifier用于处理亚洲字符。由于我没有使用它们,我知道这个补丁很好。谢谢你的阅读。
答案 0 :(得分:2)
请它适合我的工作
/^[\p{L}-. ]*$/u
^
字符串的开头[ ... ]*
以下零个或多个:\p{L}
Unicode字母字符–
破折号.
期$
字符串结尾/u
在PHP中启用Unicode模式实施例
$str= ‘Füße’;
if (!preg_match(“/^[\p{L}-. ]*$/u”, $str))
{
echo ‘error’;
}
else
{
echo “success”;
}
答案 1 :(得分:1)
u修饰符使正则表达式期望utf-8输入。这表明ZF期望utf-8编码输入,而不是ISO-8859-1(我对ZF不太熟悉,所以我只是在这里猜测。)
如果是这种情况,您必须utf-8 encode ü
才能在网址中使用它。然后它将成为:mysite.local/citytest/M%C3%BCnchen
请注意,由于应用程序的其余部分可能会使用ISO-8859-1(默认情况下为PHP&lt; = 5),因此您必须先使用utf8_decode对变量进行显式解码,然后才能使用它
答案 2 :(得分:1)
问题如下:
使用/ u模式修饰符可以防止 被篡改的话,而是 PCRE跳过字符串 代码值大于127。 因此,\ w将不匹配 多字节(非低ascii)字 所有(但也不会返回部分) 它)。从pcrepattern手册页;
在UTF-8模式下,带有值的字符 大于128永远不会匹配\ d,\ s, 或\ W,并始终匹配\ D,\ S和 \ W。即使在Unicode时也是如此 角色属性支持是 可用。
来自Handling UTF-8 with PHP。 因此,如果您的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之前)没有UTF-8编码输入到地址文本框中的URL(如果未在about:config中指定),并且IE在其选项中有一个复选框,用于为其URL选择常规和UTF-8编码。但是,如果您单击页面中的链接,则两个浏览器都使用给定编码中的URL(UTF-8页面上的UTF-8)。因此,您无法确定将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('/ß/', '/&(..)lig;/', '/&([aouAOU])uml;/', '/&(.)[^;]*;/', '/\W/'),
array('ss', '$1', '$1e', '$1', '-'),
$name);
$name=preg_replace('/-{2,}/', '-', $name);
return trim($name, '-');
}