Как установить (UTF8) модификатор для RegEx маршрута RegEx в Zend Framework 2?

У меня возникают проблемы с (немецкими) специальными символами в URI и вы хотите попытаться разрешить его с помощью RegEx Route и модификатором шаблона 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, ни для тех, у кого нет специальных символов.

Как правильно установить модификатор?

Solutions Collecting From Web of "Как установить (UTF8) модификатор для RegEx маршрута RegEx в Zend Framework 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); } } не <?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 ?>