带有德语特殊字符的 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/(?<city>[\\pL]*)/u'
这样的正则表达式
解决方案是使用自定义 RegEx 路由。 Here 就是一个例子。
【讨论】:
谢谢!这对我不起作用,但也许我错误地使用了你的正则表达式。我已将'city' => '[a-zA-ZäöüÄÖÜß0-9_-]*',
替换为 'city' => '/^\pL[\pL _.-]+$/u',
也许这是一个糟糕的例子,它只是为了说明 /u 标志。试试 '/[\pL]+/u'
终于成功了!感谢您对修饰符的重要提示!
我已经发布了解释和解决方案的链接,作为您答案的补充。什么意思?
我将此添加到我的修饰符中:/[\pL]+/u 但仍然无法正常工作。 Automatix,可以分享一下你用过的吗?以上是关于带有德语特殊字符的 URI 在 Zend Framework 2 中不起作用(错误 404)的主要内容,如果未能解决你的问题,请参考以下文章
德语特殊字符 Ää、Öö、Üü、ß 在 LiveLink 或 opentext 中显示不正确