我有自定义路由器,我必须访问此自定义路由器中的Zend\Navigation
。我在谷歌搜索,询问和搜索,没有结果:/
我只需要在Alias :: match函数中使用Zend \ Navigation查找带有'link'参数的节点。
这是我的module.config.php:
'navigation' => array(
'default' => array(
'account' => array(
'label' => 'Account',
'route' => 'node',
'pages' => array(
'home' => array(
'label' => 'Dashboard',
'route' => 'node',
'params' => array(
'id' => '1',
'link' => '/about/gallery'
),
),
),
),
),
),
[...]
这是我的Alias课程:
// file within ModuleName/src/ModuleName/Router/Alias.php
namespace Application\Router;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class Alias extends Http\Segment implements ServiceLocatorAwareInterface
{
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function match(Request $request, $pathOffset = null)
{
[...]
return parent::match($request, $pathOffset);
}
}
编辑:
现在我知道我应该将服务管理器注入我的自定义路由器。如果你知道怎么做,请告诉我:))
编辑:
好吧,它不是自定义路由器而是路由。我的错。我正在谈论#zftalk
irc chanell和AliasSegment
类应该实现ServiceLocatorAwareInterface
。好的我已经尝试过但现在又出现了另一个问题。 击>
在setServiceLocator
函数中,我无法获得service locator
。它返回null对象,但$serviceLocator
是类Zend\Mvc\Router\RoutePluginManager
。
public function setServiceLocator(ServiceLocatorInterface $serviceLocator){
$sl = $serviceLocator->getServiceLocator();
var_dump($sl); // NULL
}
如何从中获取Zend导航的任何想法?
EDITED
对应@mmmshuddup所说的,我已经改变了我的自定义路由器类。 (新版本在上面)。同样在我的Module.php
onBootstrap
函数中,我添加了这一行:
$sm->setFactory('Navigation', 'Zend\Navigation\Service\DefaultNavigationFactory', true);
导航工作并在route
之前实例化,因此它应该在我的Alias类中可见,但事实并非如此。
我已经在match
类中添加了Alias
这一行:
$servicesArray = $this->getServiceLocator()->getRegisteredServices();
和$servicesArray
几乎是空的。没有服务,没有工厂。在设置新工厂(如上所述)之后插入onBootstrap
的同一行返回带有navigation
和其他服务的数组。
问题是:如何与我的自定义路由器共享此阵列(或ServiceManager):Alias
?
我不得不说,我想要做的就是在ZF1中做到这一点非常容易。
修改
我找到了解决方案。答案如下:
答案 0 :(得分:2)
这是因为对象本身实际上没有any properties declared。但如果你这样做:
echo get_class($sl);
您会看到它确实是Zend\ServiceManager\ServiceManager
您应该能够通过以下操作获取导航实例:
$nav = $sl->get('Navigation');
击> <击> 撞击>
编辑:
我只是注意到你的代码位置错误。您正在 getServiceLocator()
上调用$serviceLocator
,这已经是其中的实例。您也可以在 setServiceLocator()
中调用它。你应该把它改成:
// EDIT - file within ModuleName/src/Router/Alias.php
namespace Application\Router;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
class Alias extends Http\Segment implements ServiceLocatorAwareInterface
{
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function match(Request $request, $pathOffset = null)
{
$nav = $this->getServiceLocator()->get('Navigation');
// ...
return parent::match($request, $pathOffset);
}
}
答案 1 :(得分:1)
我找到了解决方案,但我认为这是不优雅的解决方案。然而一切都很完美。如果有人知道这个解决方案的缺点,请评论这个答案或添加另一个,更好。我不得不修改@mmmshuddup的想法(you can read the conversation)。
首先,不再需要在自定义路由类中实现ServiceLocatorAwareInterface
。
Module.php
函数中的onBootstrap
:
$app = $e->getApplication();
$sm = $app->getServiceManager();
$sm->get('translator');
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$sm->setFactory('Navigation',
'Zend\Navigation\Service\DefaultNavigationFactory', true);
$nav = $sm->get('Navigation');
$alias = $sm->get('Application\Router\Alias');
$alias->setNavigation($nav);
首先我们在Navigation
中实例化ServiceManager
工厂,然后我们的自定义路线。之后,我们可以使用setNavigation
函数将Navigation类传递到自定义路径。
要完成我们的自定义路由的实例化,我们需要在同一文件中的getServiceConfig
:
return array(
'factories' => array(
'Application\Router\Alias' => function($sm) {
$alias = new \Application\Router\Alias('/node[/:id]');
return $alias;
},
'db_adapter' => function($sm) {
$config = $sm->get('Configuration');
$dbAdapter = new \Zend\Db\Adapter\Adapter($config['db']);
return $dbAdapter;
},
)
);
这是一个棘手的部分。这个例子是暂时的。在路由时,这个类将再次被实例化,这就是为什么,我认为它不是很优雅。我们必须在构造函数中插入参数,但此时此参数的值并不重要。
自定义路线类:
// file within ModuleName/src/ModuleName/Router/Alias.php
namespace Application\Router;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
class Alias extends Http\Segment
{
private static $_navigation = null;
public function match(Request $request, $pathOffset = null)
{
//some logic here
//get Navigation
$nav = self::$_navigation;
return parent::match($request, $pathOffset);
}
public function setNavigation($navigation){
self::$_navigation = $navigation;
}
}
因为第一个实例是临时的,我们必须在静态变量中收集Navigation
类。这很可怕,但效果很好。也许有一种方法只将它实例化一次并在路由配置中得到它的实例,但此时这是我的问题的最佳答案。足够简单,工作正常。