我正在开发一个Zend Framework 2应用程序,我似乎无法正确路由或知道在哪里路由它。
我有一个主机名=> webapp.foo-bar.com。我们决定添加一个Subhost => / app /到最后,这个应用程序的名称叫做>应用程序。我在页面上有一个链接,它的路线会说=> /图/页名。但当我将鼠标悬停在看起来像的链接上时:
<a href="/graph/page-name">FooBar</a>
我得到webapp.foo-bar.com/graph/page-name而不是webapp.foo-bar.com/app/graph/page-name。
我的应用程序配置是:
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'hostname',
'options' => array(
'route' => 'webapp.foo-bar.com/app',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
),
// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in, and you can access them
// using the path /application/:controller/:action
'application' => array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'aliases' => array(
'translator' => 'MvcTranslator',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
// Placeholder for console routes
'console' => array(
'router' => array(
'routes' => array(
),
),
),
);
我看到有一个选项:
<a href="<?=$this->url('application/default', array('controller' => 'graph', 'action' => 'page-name')?>">FooBar</a>
这需要在每个链接上完成,还是我们能够在配置级别完成?
谢谢!
更新
我设法让客户端使用this-&gt; url()方法,事情看起来很好。即使在jQuery部分,链接也在起作用。关于链接到另一个没有在链接中显示操作的控制器,我遇到了一个小问题。
<a href="<?php echo $this->url('foo-bar', array('action' => 'bar-foo'))?>?year=2015"</a>
带回webapp.foo-bar.com/app/foo-bar?year=2015。我希望它返回webapp.foo-bar.com/app/foo-bar/bar-foo?year=2015。这是foo-bar控制器中的配置还是可以在this-url()中完成?
万分感谢所有帮助。真的很喜欢它!
答案 0 :(得分:1)
如果两个应用共享同一个域,则您的配置无效。我的配置文件版本如下。
P.S。我创建了单独的模块Sample,因此它不会干扰Application config。
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use \Sample\Controller\IndexController;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'v2' => [
'type' => Segment::class,
'options' => [
'route' => '/v2/app',
'defaults' => [
'controller' => IndexController::class,
'action' => 'index',
],
],
'child_routes' => [
'index' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => IndexController::class,
'action' => 'index',
],
],
],
'application' => [
'type' => Segment::class,
'options' => [
'route' => '[/:action]',
'defaults' => [
'controller' => IndexController::class,
'action' => 'index',
],
],
]
],
],
],
],
'controllers' => [
'factories' => [
IndexController::class => InvokableFactory::class,
],
],
'view_manager' => [
'template_path_stack' => [
__DIR__ . '/../view',
],
],
];
这是您创建指向该应用程序的链接的方式:
<?php echo $this->url("v2/application", ['action' => 'page-name']) ?>
答案 1 :(得分:1)
在ZF2中,路由映射到特定的控制器类及其操作或方法,因此它们可以是任何模块。例如,此路线graph/page-name
可能会映射到GraphController
及其方法pageNameAction()
。但那可以是任何其他控制器及其动作。这取决于您的需求。
现在让我们来看一个路线的类型。 ZF中有一些路由插件。这些可用于指定路线的类型。例如,Hostname
指定域名和子域名subdomain.domain.tld
。但是您正在使用domain.tld/v2/app
。 Hostname
类型不允许/
中的'route' => 'subdomain.domain.tld'
。所以在这种情况下这不起作用。
您可以在不创建线程中所述的任何子域的情况下获得此类端点(domain.tld/v2/app
)。这就是为什么MVC模式,Framework更方便。您可以在ZF应用程序中为不同目的(domain.tld/v1/abc
domain.tld/v2/mno
domain.tld/v3/xyz
等)创建大量端点。它们可以映射到不同模块的不同控制器和动作。
所以你不需要像你问的那样依赖子域名。
你还说你需要domain.tld/graph/page-name
,它实际上是domain.tld/v2/app/graph/page-name
。这意味着如果我没有错,你想要从网址隐藏这个部分v2/app
。但这仍然是一个挑战。
如果您在此graph/page-name
下使用v2/app/graph/page-name
,则可以按如下方式定义路线
// Top key of a route
'v2app' => [
'type' => 'Segment',
'options' => [
'route' => '/v2/app',
'defaults' => [
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'default' => [
'type' => 'Segment',
'options' => [
'route' => '/',
'defaults' => [
'controller' => 'Application\Controller\Index',
'action' => 'index',
],
],
],
'graph' => [
'type' => 'Segment',
'options' => [
'route' => '[/:controller/:action]',
'defaults' => [
'controller' => 'Application\Controller\Graph',
'action' => 'pageName',
],
],
],
],
],
您可以通过更正模块名称,控制器名称等将其添加到任何module.config.php
的任何路段部分。但请注意,多条路线的相同配置会让您不满意。
现在要输出这些路线,请使用以下代码片段
echo $this->url('v2app/graph', [], [], true);
echo $this->url(null, ['controller' => 'graph', 'action' => 'page-name']);
// outputs
// /v2/app/graph/page-name
虽然v2app
是您的主要路线密钥,graph
是其路径。
现在您已经说过应该如何实现链接了。如果您想将它们显示为菜单,则不必像您所说的那样编写代码。你可以follow this to implement links as menu。但请记住,在为导航构建阵列时为路径键提供值(路线的顶部键)。
以下示例来自此路线graph/page-name
[
'label' => 'Graph',
// route name not route pattern
'route' => 'graph', // not /graph/page-name
],
否则,如果您想在页面正文中显示链接,请使用上面使用的$this->url()
帮助程序。
请参阅此DOC了解Hostname
类型。
如果我们无法帮助您,请ask this here
答案 2 :(得分:1)
只需创建一个包含自己的url
实现
/**
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
* @return void
*/
public function setLayout($e)
{
// Should return your customization
$viewModel = $e->getViewModel();
在这种情况下,您的所有$this->url()
将直接执行相同的操作:
$this->url('application/default', array('controller' => 'graph', 'action' => 'page-name')
作为自定义渲染的部分示例:
$customStrategy = $app->getServiceManager()->get('{Your class name}');
$view->getEventManager()->attach($customStrategy, 1); // 1 - means priority
在课堂内
preg_replace_callback('/<a href=\\"([^\\"]*)\\">(.*)<\\/a>/iU', function ($matches) {
// do whatever you need for each URL
}, $content);
或者它可以使用DOM对象(但它依赖于你的代码有效性):
$xpath = new \DOMXPath((new \DOMDocument)->loadHTML($content));
foreach ($xpath->query('//a[href]') as $link) {
// ...
}
答案 3 :(得分:0)
为此目的有一种方法。你可以试试这个。为此,您需要创建一个自定义路由插件,然后将其设置为路由指向Graph
控制器及其目标方法pageNameAction()
,在本例中。请按照以下步骤操作。
此处graph/page-name
将作为v2/app/graph/page-name
使用,这意味着以下链接可以按预期工作。
<a href="/graph/page-name">FooBar</a>
请从here获取自定义路由插件。使用命名空间src/YourModuleName/Route
将其放在此YourModuleName\Route
目录下。
请注意,您需要将'template_prefix' => 'yourmodulename',
替换为您自己的模块名称和所有小写字母。将通过匹配场景后面的此图案yourmodulename/controller/action-name
来搜索视图模板。
'v2app' => [
'type' => 'Segment',
'options' => [
'route' => '[/v2/app]',
'defaults' => [
'controller' => 'YourModuleName\Controller\Index',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'graph' => [
// We call the custom route plugin thus
'type' => 'YourModuleName\Route\AppRoute',
'options' => [
'dir_name' => __DIR__ . '/../view',
'template_prefix' => 'yourmodulename',
'filename_pattern' => '/[a-z0-9_\-]+/',
'defaults' => [
'controller' => 'YourModuleName\Controller\Graph',
'action' => 'pageName',
],
],
],
],
],
现在将pageNameAction()
格式化为以下
public function pageNameAction()
{
// Get path to view template from route params
$pageTemplate = $this->params()->fromRoute('page', null);
// If path is not valid
if($pageTemplate == null) {
$this->getResponse()->setStatusCode(404);
return;
}
$viewModel = new ViewModel();
// Here we set template to be rendered for `v2/app/graph/page-name`
$viewModel->setTemplate($pageTemplate);
return $viewModel;
}
如果需要在视图脚本中输出链接,请使用这种方式
echo $this->serverUrl('/graph/page-name');
希望这会对你有帮助!