带有德语特殊字符的 URI 不起作用(错误 404)。我已经遇到过这个问题( here ),并且已通过 unicode modifier 解决了和一个custom view helper ,使用它。
现在我对 Segment
有同样的问题子路由,但这次使用 unicode 标识符和自定义 View 助手的方法不起作用。
所有请求如 sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß
或sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123
以 404
结尾错误。
/module/Catalog/config/module.config.php
<?php
return array(
...
'router' => array(
'routes' => array(
'catalog' => array(
...
),
'city' => array(
...
),
// works correctly, if I remove the child route
'sport' => array(
'type' => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
'options' => array(
'regex' => '/catalog/(?<city>[\p{L}\p{Zs}]*)/(?<sport>[\p{L}\p{Zs}]*)',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-courses',
),
'spec' => '/catalog/%city%/%sport%',
),
'may_terminate' => true,
'child_routes' => array(
'courses' => array(
'type' => 'segment',
'options' => array(
'route' => '[/page/:page]',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-courses',
),
),
'may_terminate' => true,
),
)
),
),
),
...
);
我也尝试过 UnicodeRegex
子路线:
'sport' => array(
'type' => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
'options' => array(
'regex' => '/catalog/(?<city>[\p{L}\p{Zs}]*)/(?<sport>[\p{L}\p{Zs}]*)',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-courses',
),
'spec' => '/catalog/%city%/%sport%',
),
'may_terminate' => true,
'child_routes' => array(
'courses' => array(
'type' => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
'options' => array(
'regex' => '/page/(?<page>[\p{N}]*)',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-courses',
),
'spec' => '/page/%page%',
),
'may_terminate' => true,
),
)
),
UnicodeRegex
参见here
UnicodeSegment
扩展Zend\Mvc\Router\Http\Segment
并完成ALL preg_match(...)
的输入调用 u
:
-
'((\G(?P<literal>[^:{\[\]]*)(?P<token>[:{\[\]]|$)))u'
-
'(\G\{(?P<name>[^}]+)\}:?)u'
-
'((\G(?P<name>[^:/{\[\]]+)(?:{(?P<delimiters>[^}]+)})?:?))u'
-
'(\G(?P<literal>[^}]+)\})u'
-
'(\G' . $this->regex . ')u'
-
'(^' . $this->regex . '$)u'
如何让它工作?
最佳答案
刚刚看了一下,您需要更改 UnicodeRegex
匹配方法,以便它返回匹配的 url 部分的正确长度,这里尝试修复该问题,这似乎使用您的设置(至少对我来说)
public function match(Request $request, $pathOffset = null)
{
if (!method_exists($request, 'getUri')) {
return null;
}
$uri = $request->getUri();
$path = rawurldecode($uri->getPath());
if ($pathOffset !== null) {
$result = preg_match('(\G' . $this->regex . ')u', $path, $matches, null, $pathOffset);
} else {
$result = preg_match('(^' . $this->regex . '$)u', $path, $matches);
}
if (!$result) {
return null;
}
foreach ($matches as $key => $value) {
if (is_numeric($key) || is_int($key) || $value === '') {
unset($matches[$key]);
} else {
$matches[$key] = rawurldecode($value);
}
}
// at this point there's a mismatch between the length of the rawurlencoded path
// that all other route helpers use, so we need to match their expectations
// to do that we build the matched part from the spec, using the matched params
$url = $this->spec;
$mergedParams = array_merge($this->defaults, $matches);
foreach ($mergedParams as $key => $value) {
$spec = '%' . $key . '%';
if (strpos($url, $spec) !== false) {
$url = str_replace($spec, rawurlencode($value), $url);
}
}
// make sure the url we built from spec exists in the original uri path
if (false === strpos($uri->getPath(), $url)) {
return null;
}
// now we can get the matchedLength
$matchedLength = strlen($url);
return new RouteMatch($mergedParams, $matchedLength);
}
关于php - 在 Zend Framework 2 中无法正确解析包含特殊字符的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16097053/