Как установить модификатор (UTF8) для RegEx маршрута RegEx в Zend Framework 2?
У меня проблемы с (немецкими) специальными символами в URI, и я хочу попытаться разрешить их с помощью маршрута RegEx и модификатора шаблона PCRE для UTF-8. u
,
'router' => array(
'routes' => array(
// ...
'city' => array(
'type' => 'regex',
'options' => array(
'regex' => '/catalog/(?<city>[a-zA-Z0-9_-äöüÄÖÜß]*)\/u',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-sports',
),
'spec' => '/catalog/%city%',
),
'may_terminate' => true,
),
),
),
Но когда я его установил, маршрут вообще перестает работать (ошибка 404) - ни для URI, ни для тех, у которых нет специальных символов.
Как правильно установить модификатор?
2 ответа
Поскольку у меня уже было это открыто, вот обработчик, который решает проблему.
<?php
namespace Application\Mvc\Router\Http;
use Zend\Mvc\Router\Http\Regex;
use Zend\Mvc\Router\Http\RouteMatch;
use Zend\Stdlib\RequestInterface as Request;
class UnicodeRegex extends Regex
{
/**
* match(): defined by RouteInterface interface.
*
* @param Request $request
* @param integer $pathOffset
* @return RouteMatch
*/
public function match(Request $request, $pathOffset = null)
{
if (!method_exists($request, 'getUri')) {
return null;
}
$uri = $request->getUri();
// path decoded before match
$path = rawurldecode($uri->getPath());
// regex with u modifier
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;
}
$matchedLength = strlen($matches[0]);
foreach ($matches as $key => $value) {
if (is_numeric($key) || is_int($key) || $value === '') {
unset($matches[$key]);
} else {
$matches[$key] = $value;
}
}
return new RouteMatch(array_merge($this->defaults, $matches), $matchedLength);
}
}
Предполагая, что вы поместите файл в Application/Mvc/Router/Http/UnicodeRegex
Ваше определение маршрута должно выглядеть так
'router' => array(
'routes' => array(
// ...
'city' => array(
'type' => 'Application\Mvc\Router\Http\UnicodeRegex',
'options' => array(
'regex' => '/catalog/(?<city>[\p{L}]+)',
// or if you prefer, your original regex should work too
// 'regex' => '/catalog/(?<city>[a-zA-Z0-9_-äöüÄÖÜß]*)',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-sports',
),
'spec' => '/catalog/%city%',
),
'may_terminate' => true,
),
),
),
Что ж,
Я думаю, вы можете решить это так же легко, как и многие другие имели эту же проблему. Итак, взгляните на некоторые из них:
UTF-8 в * регулярных выражениях
Там используются следующие модификаторы, такие как \\s
, \\p{L}
, а также \\u
чтобы помочь вам. Я надеюсь, что это решает! Удачи.
редактировать
Смотрите мой собственный тест:
<?php
$toss_the_dice = utf8_decode ("etc/catalog/Nürnberg");
preg_match ('/\/catalog\/([\\s\\p{L}]*)/m', $toss_the_dice, $dice);
echo utf8_encode ($dice[1]);
// Now it prints
// Nürnberg
?>
Вы можете понять?
Редактировать 2
Это может быть лучше для вас!
<?php
$toss_the_dice = "etc/catalog/Nürnberg";
preg_match ('/\/catalog\/([\\s\\p{L}]*)/u', $toss_the_dice, $dice);
echo $dice[1];
// Now it also prints
// Nürnberg
?>