如何在ZF2中的控制台控制器中创建URL?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在ZF2中的控制台控制器中创建URL?相关的知识,希望对你有一定的参考价值。
我有一个控制台控制器和一个发送电子邮件的动作(在下面的module.config.php中定义)
'console' => array(
'router' => array(
'routes' => array(
'cronroute' => array(
'options' => array(
'route' => 'sendEmails',
'defaults' => array(
'controller' => 'ApplicationControllerConsole',
'action' => 'send-emails'
)
)
),
)
)
),
在操作中,我想发送一封电子邮件,其中包含指向该网站上其他操作的链接。这通常使用URL View Helper来完成,但由于Request类型是Console而不是HTTP,因此不起作用。我试图创建一个HTTP请求,但我不知道如何给它站点域或Controller / Action链接。
我的控制器代码:
$vhm = $this->getServiceLocator()->get('viewhelpermanager');
$url = $vhm->get('url');
$urlString = $url('communication', array('action' => 'respond', 'id' => $id,
array('force_canonical' => true));
这会引发错误:
======================================================================
The application has thrown an exception!
======================================================================
ZendMvcRouterExceptionRuntimeException
Request URI has not been set
如何在具有站点方案,域和路径/到/ action的控制台控制器中创建HTTP请求?我如何将其传递给URL View Helper?
以下是此问题的解决方法:
<?php
// Module.php
use ZendViewHelperServerUrl;
use ZendViewHelperUrl as UrlHelper;
use ZendUriHttp as HttpUri;
use ZendConsoleConsole;
use ZendModuleManagerFeatureViewHelperProviderInterface;
class Module implements ViewHelperProviderInterface
{
public function getViewHelperConfig()
{
return array(
'factories' => array(
'url' => function ($helperPluginManager) {
$serviceLocator = $helperPluginManager->getServiceLocator();
$config = $serviceLocator->get('Config');
$viewHelper = new UrlHelper();
$routerName = Console::isConsole() ? 'HttpRouter' : 'Router';
/** @var endMvcRouterHttpTreeRouteStack $router */
$router = $serviceLocator->get($routerName);
if (Console::isConsole()) {
$requestUri = new HttpUri();
$requestUri->setHost($config['website']['host'])
->setScheme($config['website']['scheme']);
$router->setRequestUri($requestUri);
}
$viewHelper->setRouter($router);
$match = $serviceLocator->get('application')
->getMvcEvent()
->getRouteMatch();
if ($match instanceof RouteMatch) {
$viewHelper->setRouteMatch($match);
}
return $viewHelper;
},
'serverUrl' => function ($helperPluginManager) {
$serviceLocator = $helperPluginManager->getServiceLocator();
$config = $serviceLocator->get('Config');
$serverUrlHelper = new ServerUrl();
if (Console::isConsole()) {
$serverUrlHelper->setHost($config['website']['host'])
->setScheme($config['website']['scheme']);
}
return $serverUrlHelper;
},
),
);
}
}
当然,您必须在config中定义默认主机和方案值,因为无法在控制台模式下自动检测它们。
我不敢相信,但我做到了:)
希望它能为你们所有人服务。
在使用fromRoute()函数的控制器中,我添加了以下行:
$event = $this->getEvent();
$http = $this->getServiceLocator()->get('HttpRouter');
$router = $event->setRouter($http);
$request = new endHttpRequest();
$request->setUri('');
$router = $event->getRouter();
$routeMatch = $router->match($request);
var_dump($this->url()->fromRoute(
'route_parent/route_child',
[
'param1' => 1,
'param2' => 2,
)
);
输出:
//mydomain.local/route-url/1/2
当然route_parent / route_child不是控制台路由,而是HTTP路由:)
感谢@Alexey Kosov的回复。当您的应用程序在域'/'之后在子目录而不是根目录下工作时,您可能会遇到问题。
你必须添加:
$router->setBaseUrl($config['website']['path']);
整码:
<?php
// Module.php
use ZendViewHelperServerUrl;
use ZendViewHelperUrl as UrlHelper;
use ZendUriHttp as HttpUri;
use ZendConsoleConsole;
use ZendModuleManagerFeatureViewHelperProviderInterface;
class Module implements ViewHelperProviderInterface
{
public function getViewHelperConfig()
{
return array(
'factories' => array(
'url' => function ($helperPluginManager) {
$serviceLocator = $helperPluginManager->getServiceLocator();
$config = $serviceLocator->get('Config');
$viewHelper = new UrlHelper();
$routerName = Console::isConsole() ? 'HttpRouter' : 'Router';
/** @var endMvcRouterHttpTreeRouteStack $router */
$router = $serviceLocator->get($routerName);
if (Console::isConsole()) {
$requestUri = new HttpUri();
$requestUri->setHost($config['website']['host'])
->setScheme($config['website']['scheme']);
$router->setRequestUri($requestUri);
$router->setBaseUrl($config['website']['path']);
}
$viewHelper->setRouter($router);
$match = $serviceLocator->get('application')
->getMvcEvent()
->getRouteMatch();
if ($match instanceof RouteMatch) {
$viewHelper->setRouteMatch($match);
}
return $viewHelper;
},
'serverUrl' => function ($helperPluginManager) {
$serviceLocator = $helperPluginManager->getServiceLocator();
$config = $serviceLocator->get('Config');
$serverUrlHelper = new ServerUrl();
if (Console::isConsole()) {
$serverUrlHelper->setHost($config['website']['host'])
->setScheme($config['website']['scheme']);
}
return $serverUrlHelper;
},
),
);
}
}
更新:这篇文章的正确答案可以在这里找到:Stackoverflow: Using HTTP routes within ZF2 console application
嗯,你非常接近这个,但你没有使用Url
插件。如果您进一步深入了解控制器插件的ZF2文档,您可以找到解决方案。
参见:ZF2 Documentation - Controller plugins
您的ConsoleController
必须实现以下之一,才能检索Controller插件:
AbstractActionController
AbstractRestfulController
setPluginManager
好吧,如果你还没有完成,我建议用AbstractActionController
扩展你的控制器。
如果您使用AbstractActionController
,您可以简单地调用$urlPlugin = $this->url()
,因为AbstractActionController
有一个__call()
实现为您检索插件。但你也可以使用:$urlPlugin = $this->plugin('url');
因此,为了生成邮件的URL,您可以在控制器中执行以下操作:
$urlPlugin = $this->url();
$urlString = $urlPlugin->fromRoute(
'route/myroute',
array(
'param1' => $param1,
'param2' => $param2
),
array(
'option1' => $option1,
'option2' => $option2
)
);
您现在可以将此URL传递给viewModel
或在viewModel中使用URL viewHelper,但这取决于您。
尽量避免在控制器中使用viewHelpers,因为我们已经为这种情况提供了插件。
如果你想知道AbstractActionController
有什么方法,这里是ZF2 ApiDoc - AbstractActionController
为了完成这项工作,您必须使用适当的结构设置路由配置:
// This can sit inside of modules/Application/config/module.config.php or any other module's config.
array(
'router' => array(
'routes' => array(
// HTTP routes are here
)
),
'console' => array(
'router' => array(
'routes' => array(
// Console routes go here
)
)
),
)
如果您有控制台模块,只需坚持使用控制台路径路径。不要忘记控制台键及其下方的所有路线!请查看文档以供参考:ZF2中的Zend Db如何控制事务?
@Url.Action 添加“amp;”在控制器中创建空值的参数之间?