ZF2 имя хоста соответствует URL сборки и 404

У меня есть следующий код для сопоставления маршрута с именем хоста;

'router' => [
'router_class' => 'Zend\Mvc\Router\Http\TranslatorAwareTreeRouteStack',
'routes' => [
'website' => [
'type' => 'hostname',
'may_terminate' => true,
'options' => [
'route' => ':locale.domain.:tld',
'constraints' => [
'language' => '(nl|en)',
'tld' => '(dev|org)',
],
],
]
],
],

И некоторые маршруты, чтобы соответствовать URI.

Так что в Dev я могу иметь такие маршруты, как en.domain.dev а также nl.domain.dev, Перевод маршрута также работает как шарм, но тогда возникают мои «проблемы»

1. Соберите URL

Для каждого URL мне сейчас нужно locale а также tld переменная. Для этого я делаю <?= $this->url('website/languages', [], true); ?>, но это делает его беспорядком. Потому что я хочу использовать только TLD и локаль текущего маршрута.

Поэтому я пришел с решением расширить помощник по просмотру URL. И установить locale а также tld параметр, когда он не был установлен в соответствии с маршрутом. Это сработало для 1 «незначительной» проблемы, см. 2. Но мне было интересно, есть ли лучшее решение для этого.

2. 404 пага

В 1 я использую текущий маршрут, чтобы получить locale/tld собрать URL это все работает, за исключением 404 страницы. Потому что, чем нет маршрута, очевидно.

Я начал копать arround и когда я нашел роутер (из service locator). Я пытался найти маршрут для website он только вернулся Zend\Mvc\Router\Http\Part,
protected $route был Zend\Mvc\Router\Http\Hostname который не доступен. Так что не повезло.

Единственный способ, которым я получил маршрут Hostname, состоял в том, чтобы создать его сам, чего я действительно не хочу делать.

Итак, вопрос в том, как легко использовать параметры имени хоста и получить параметры имени хоста на странице 404?

Я знаю, что, например, test.domain.test не будет соответствовать имени хоста и предоставит неверное имя хоста, но это вопрос Nginx. Поэтому Nginx позаботится о том, чтобы имя хоста всегда было правильным

0

Решение

Ну, я продолжал искать и думать и пришел с «решением».

Решать 2. Я создал слушатель, который слушает на MvcEvent::EVENT_DISPATCH_ERROR,

Код;

// use are above the class declaration
use Zend\Mvc\Router\Http\TranslatorAwareTreeRouteStack;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\Http\PhpEnvironment\Request;
use Zend\Mvc\Router\Http\RouteMatch;
use Zend\Mvc\MvcEvent;

public function onDispatchError(MvcEvent $event)
{
if (is_null($event->getRouteMatch())) {
$router = $event->getRouter();
$request = $event->getRequest();

if ($router instanceof TranslatorAwareTreeRouteStack && $request instanceof Request) {
$match = $router->getRoute('website')->match($request, strlen($request->getUri()->getPath()), array(
'translator' => $router->getTranslator(),
));
if ($match instanceof RouteMatch) {
$match->setMatchedRouteName('website');
$event->setRouteMatch($match);
}
}

}
}

Что оно делает;

  1. проверить, есть ли совпадение маршрута, если нет, то это 404

  2. проверить $router является TranslatorAwareTreeRouteStack и $request это HttpRequest

  3. проложить маршрут для website (это маршрут для имени хоста`

  4. тогда это соответствует ему (хитрость в том, что смещение установлено, поэтому проверяется только имя хоста)

  5. устанавливает имя, соответствующее маршруту (если не установлено, пусто, что приведет к проблемам)

  6. затем в событие вводится сопоставление маршрута

Решать 1. Теперь у меня всегда был доступ к route match чтобы я мог творить магию. Я продлил url viewhelper,

public function __invoke(
$name = null,
$params = array(),
$options = array(),
$reuseMatchedParams = false
) {
if ($this->routeMatch instanceof RouteMatch) {
foreach(['locale', 'tld'] as $key) {
if (!array_key_exists($key, $params)) {
$params[$key] = $this->routeMatch->getParam($key);
}
}
}

// This is needed for the magic that can happen when `reuseMatchedParams` is used at the third position
if (is_bool($options)) {
$reuseMatchedParams = $options;
$options = array();
}

return parent::__invoke(
$name,
$params,
$options,
$reuseMatchedParams
);
}

Не самый элегантный метод, но пока он работает

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]