带有德语特殊字符的 URI 在 Zend Framework 2 中不起作用(错误 404)

Posted

技术标签:

【中文标题】带有德语特殊字符的 URI 在 Zend Framework 2 中不起作用(错误 404)【英文标题】:URIs with german special characters don't work (error 404) in Zend Framework 2 【发布时间】:2013-03-16 02:54:24 【问题描述】:

我想获取一个城市列表,其中每个城市名称都被链接并引用该城市的页面:

链接(在视图脚本中创建)如下所示:

http://project.loc/catalog/Berlin (in the html source code url-encoded: Berlin)
http://project.loc/catalog/Erlangen (in the HTML source code url-encoded: Erlangen)
http://project.loc/catalog/Nürnberg (in the HTML source code url-encoded: N%C3%BCrnberg)

“Berlin”、“Erlangen”等有效,但如果城市名称包含德语特殊字符(äöüÄÖÜß) 像“纽伦堡”一样,出现 404 错误:

发生 404 错误页面未找到。请求的 URL 不能是 通过路由匹配。没有可用的例外

为什么?以及如何让它发挥作用?

提前致谢!

编辑:

我的路由器设置:

'router' => array(
    'routes' => array(
        'catalog' => array(
            'type'  => 'literal',
            'options' => array(
                'route' => '/catalog',
                'defaults' => array(
                    'controller' => 'Catalog\Controller\Catalog',
                    'action'     => 'list-cities',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'city' => array(
                    'type'  => 'segment',
                    'options' => array(
                        'route' => '/:city',
                        'constraints' => array(
                            'city'  => '[a-zA-ZäöüÄÖÜß0-9_-]*',
                        ),
                        'defaults' => array(
                            'controller' => 'Catalog\Controller\Catalog',
                            'action'     => 'list-sports',
                        ),
                    ),
                    'may_terminate' => true,
                    'child_routes' => array(
                    // ...
                    ),
                ),
            ),
        ),
    ),
),

【问题讨论】:

这与你定义的constraints不匹配不是很明显吗? 是的,你是对的。我刚刚编辑了路由器设置。它仍然无法正常工作。 您展示了 URL 的“外观”——但是您是否为这些特殊字符使用了正确的 URL 编码? 不,我没有。我将城市名称设置为 URI,以便它们如何来自数据库($city->name 而不是 urlencode($city->name))。 如果您自己不对 URL 中的特殊字符进行 urlencode,则将其留给客户端 - 这样您很容易遇到使用的字符编码问题。 【参考方案1】:

您需要更改约束,可以使用匹配 UTF8 字符的正则表达式,如下所示:

'/[\pL]+/u'

注意 /u 修饰符(unicode)。

编辑:

问题是resolved。

解释:

RegEx 路由将 URI 与 preg_match(...) 匹配(Zend\Mvc\Router\Http\Regex 的 116 或 118 行)。为了使用“特殊字符”(128+)来处理字符串,必须将模式修饰符u 传递给preg_match(...)。像这样:

$thisRegex = '/catalog/(?<city>[\pL]*)';
$regexStr = '(^' . $thisRegex . '$)u'; // <-- here
$path = '/catalog/Nürnberg';
$matches = array();
preg_match($regexStr, $path, $matches);

而且由于 RegEx Route 将一个 url 编码的字符串传递给 preg_match(...),因此需要先对字符串进行解码:

$thisRegex = '/catalog/(?<city>[\pL]*)';
$regexStr = '(^' . $thisRegex . '$)u';
$path = rawurldecode('/catalog/N%C3%BCrnberg');
$matches = array();
preg_match($regexStr, $path, $matches);

RegEx Route 中没有提供这两个步骤,因此 preg_match(...) 会得到一个类似 '/catalog/N%C3%BCrnberg' 的 steing 并尝试将其加工成一个像 '/catalog/(?&lt;city&gt;[\\pL]*)/u' 这样的正则表达式

解决方案是使用自定义 RegEx 路由。 Here 就是一个例子。

【讨论】:

谢谢!这对我不起作用,但也许我错误地使用了你的正则表达式。我已将 'city' =&gt; '[a-zA-ZäöüÄÖÜß0-9_-]*', 替换为 'city' =&gt; '/^\pL[\pL _.-]+$/u', 也许这是一个糟糕的例子,它只是为了说明 /u 标志。试试 '/[\pL]+/u' 终于成功了!感谢您对修饰符的重要提示! 我已经发布了解释和解决方案的链接,作为您答案的补充。什么意思? 我将此添加到我的修饰符中:/[\pL]+/u 但仍然无法正常工作。 Automatix,可以分享一下你用过的吗?

以上是关于带有德语特殊字符的 URI 在 Zend Framework 2 中不起作用(错误 404)的主要内容,如果未能解决你的问题,请参考以下文章

德语特殊字符在 WordPress 架构中不起作用

德语的最佳 MySQL 排序规则是啥

使用 URI 复制时不支持文件名中的特殊字符

德语特殊字符 Ää、Öö、Üü、ß 在 LiveLink 或 opentext 中显示不正确

允许在 UITextfield ios 中使用德语 UMLAUT 字符

Java字符串替换特殊字符(保加利亚语,波兰语,德语)[重复]