在Zend Framework 2中无法正确解析Route Mit特殊字符 [英] Route mit special characters are not parsed correctly in Zend Framework 2
问题描述
带有德语特殊字符的URI不起作用(错误404).我已经遇到了这个问题( unicode修饰符和
URIs with german special characters don't work (error 404). I've already had this problem (here) and it has been resolved with the unicode modifier and a custom view helper, that uses it.
现在我对Segment
子路由存在相同的问题,但是这次使用unicode标识符和自定义视图助手的方法不起作用.
Now I have the same issue with a Segment
child route, but this time the approach with the unicode identifier and a custom view helper isn't working.
Alle请求(例如sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß
或sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123
)以404
错误结束.
Alle requests like sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß
or sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123
are ending with a 404
error.
/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
子路线:
I've also tried it with a UnicodeRegex
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' => '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
请参见此处
UnicodeSegment
扩展Zend\Mvc\Router\Http\Segment
并使用u
完成所有preg_match(...)
呼叫的输入:
Extends Zend\Mvc\Router\Http\Segment
and completes the input of ALL preg_match(...)
calls with 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'
'((\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
match方法,以便它为匹配的url部分返回正确的长度,这是一种尝试修复此问题的方法,至少在您的设置中似乎起作用(至少对我而言)
Just had a look at this, you need to change the UnicodeRegex
match method so that it returns the correct length for the part of the url it matched, here's an attempt to fix that, which seems to be working (at least for me) with your setup
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);
}
这篇关于在Zend Framework 2中无法正确解析Route Mit特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!