У меня возникают проблемы с (немецкими) специальными символами в 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, ни для тех, у кого нет специальных символов.
Как правильно установить модификатор?
Поскольку у меня уже было это открытое, это обработчик, который решает проблему.
<?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, ), ), ),
Что ж,
Я думаю, вы можете решить эту проблему так же легко, как и многие другие. Поэтому взгляните на некоторые из них:
Для этого вам нужны следующие модификаторы, такие как \\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 ?>