[英]ZF2 hostname match assemble url and 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相匹配的路线。
因此,在开发人员中,我可以拥有诸如en.domain.dev
和nl.domain.dev
类的路由。 路线的翻译也像咒语一样起作用,但是后来我的“问题”出现了
1.组装网址
对于每个网址,我现在都需要locale
和tld
变量。 为此,我要做<?= $this->url('website/languages', [], true); ?>
<?= $this->url('website/languages', [], true); ?>
,但那一团糟。 因为我只想使用当前路由的TLD和语言环境。
因此,我提供了扩展URL视图帮助程序的解决方案。 并在未使用路由匹配设置时设置locale
和tld
参数。 这适用于1个“次要”问题,请参见2。但想知道是否有更好的解决方案。
2. 404 paga
在1中,我使用当前的路由匹配来获取locale
/ tld
来组装url,这一切都适用,除了404页面。 因为没有路由匹配,所以很明显。
我开始挖掘周围环境,并从service locator
找到路由器。 我试图获取仅返回Zend\\Mvc\\Router\\Http\\Part
website
的路由。 protected $route
是Zend\\Mvc\\Router\\Http\\Hostname
,无法访问。 那样就没有运气了。
我获得主机名路由的唯一方法是构建自己的自我,这是我真正不想做的。
因此,问题是如何轻松重用主机名参数,并在404页面上获取主机名参数?
我知道例如test.domain.test将不匹配主机名,并将提供一个损坏的主机名,但这是Nginx的问题。 因此Nginx将确保主机名始终正确
好吧,我继续寻找和思考,并提出了“解决方案”。
解决2.解决了我创建了一个监听MvcEvent::EVENT_DISPATCH_ERROR
监听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);
}
}
}
}
它能做什么;
检查是否有路线匹配,如果没有,则为404
检查$router
是TranslatorAwareTreeRouteStack
,而$request
是HttpRequest
获取website
的路由(这是主机名的路由`
然后匹配它(技巧是设置偏移量,以便仅检查主机名)
设置路线匹配名称(如果未设置则为空,这将导致问题)
然后在事件中注入routematch
解决方法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
);
}
这不是最优雅的方法,但目前可以使用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.