Zend Framework动作助手Redirector用法实例详解
Redirector 提供另一种实现方式,帮助程序重定向到内部或者外部页面;
转向器(Redirector)助手让你使用一个转向器对象帮助程序重定向到新的URL。与_redirect()方法相比,它具有多项优势。例如能够在转向器对象中预先配置整个站点的行为,或者使用与Zend_Controller_Action::_forward()相似的gotoSimple($action, $controller, $module, $params)接口。
转向器拥有影响重定向行为的大量方法:
setCode() 设置重定向过程中使用的HTTP响应码。
setExit() 在重定向后强制执行exit()方法。默认已设定。
setGotoSimple()设置默认的URL,当没有提供参数给gotoSimple()方法时转向该URL。可以使用类似Zend_Controller_Action::_forward()的API:setGotoSimple($action, $controller = null, $module = null, array $params = array());
setGotoRoute()设置基于一个注册路由器的URL。通过传入一个键/值数组和一个路由器名,它将根据路由器的类型和定义来组织URL。
setGotoUrl()设置默认的URL,当没有参数传入gotoUrl(),将使用该URL。接受单个URL字符串。
setPrependBase()在setGotoUrl()、gotoUrl()或者gotoUrlAndExit()指定的URL前面,加入请求对象的基地址(base URL)。
setUseAbsoluteUri()强制转向器在重定向时使用绝对的URI。当该选项设定后,将使用$_SERVER['HTTP_HOST']、 $_SERVER['SERVER_PORT']和 $_SERVER['HTTPS']以及重定向方法指定的URL,来形成一个完整的URI。该选项目前默认关闭,将来的版本可能会默认开启。
此外,转向器中还有大量方法来执行实际的重定向。
gotoSimple()使用setGotoSimple()(类似_forward()的API)来构建URL并执行重定向。
gotoRoute()使用setGotoRoute()(路由组装route-assembly)来构建URL并执行重定向。
gotoUrl()使用setGotoUrl() URL字符串)来构造URL并执行重定向。
最后,你可以在任何时刻使用getRedirectUrl()确定当前的重定向URL。
基础用例
Example #5 设定选项
这个例子改变了几个选项,包括设定重定向时使用的HTTP状态码为303,重定向时不默认退出,以及定义了默认的URL供重定向使用。
class SomeController extends Zend_Controller_Action { /** * Redirector - defined for code completion * * @var Zend_Controller_Action_Helper_Redirector */ protected $_redirector = null; public function init() { $this->_redirector = $this->_helper->getHelper('Redirector'); // Set the default options for the redirector // Since the object is registered in the helper broker, these // become relevant for all actions from this point forward $this->_redirector->setCode(303) ->setExit(false) ->setGotoSimple("this-action", "some-controller"); } public function myAction() { /* do some stuff */ // Redirect to a previously registered URL, and force an exit // to occur when done: $this->_redirector->redirectAndExit(); return; // never reached } }
Example #6 使用默认设定
这个例子假定使用默认设定,也就意味着任何重定向将导致立即退出。
// ALTERNATIVE EXAMPLE class AlternativeController extends Zend_Controller_Action { /** * Redirector - defined for code completion * * @var Zend_Controller_Action_Helper_Redirector */ protected $_redirector = null; public function init() { $this->_redirector = $this->_helper->getHelper('Redirector'); } public function myAction() { /* do some stuff */ $this->_redirector ->gotoUrl('/my-controller/my-action/param1/test/param2/test2'); return; // never reached since default is to goto and exit } }
Example #7 使用goto()的_forward()API
gotoSimple()'s API 模拟了Zend_Controller_Action::_forward()。主要的不同在于它通过传入的参数构造URL,使用默认路由器的默认格式:module/:controller/:action/*。然后重定向而不是继续动作链循环。
class ForwardController extends Zend_Controller_Action { /** * Redirector - defined for code completion * * @var Zend_Controller_Action_Helper_Redirector */ protected $_redirector = null; public function init() { $this->_redirector = $this->_helper->getHelper('Redirector'); } public function myAction() { /* do some stuff */ // Redirect to 'my-action' of 'my-controller' in the current // module, using the params param1 => test and param2 => test2 $this->_redirector->gotoSimple('my-action', 'my-controller', null, array('param1' => 'test', 'param2' => 'test2' ) ); } }
Example #8 通过gotoRoute()使用路由组装(route assembly)
下面的例子使用了路由器的assemble()方法,基于传入参数的关联数组来创建URL。假定下面的路由已经注册:
$route = new Zend_Controller_Router_Route( 'blog/:year/:month/:day/:id', array('controller' => 'archive', 'module' => 'blog', 'action' => 'view') ); $router->addRoute('blogArchive', $route);
给定一个数组,其中年份为2006,月份为4,日期为24,id为42,据此可以组装URL/blog/2006/4/24/42。
class BlogAdminController extends Zend_Controller_Action { /** * Redirector - defined for code completion * * @var Zend_Controller_Action_Helper_Redirector */ protected $_redirector = null; public function init() { $this->_redirector = $this->_helper->getHelper('Redirector'); } public function returnAction() { /* do some stuff */ // Redirect to blog archive. Builds the following URL: // /blog/2006/4/24/42 $this->_redirector->gotoRoute( array('year' => 2006, 'month' => 4, 'day' => 24, 'id' => 42), 'blogArchive' ); } }
Zend_Controller_Action_Helper_Redirector的源码。
通过源代码不难看出实现方法,以及常见的使用方法。
<?php /** * @see Zend_Controller_Action_Helper_Abstract */ require_once 'Zend/Controller/Action/Helper/Abstract.php'; /** * @category Zend * @package Zend_Controller * @subpackage Zend_Controller_Action_Helper * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_Controller_Action_Helper_Redirector extends Zend_Controller_Action_Helper_Abstract { /** * HTTP status code for redirects * @var int */ protected $_code = 302; /** * Whether or not calls to _redirect() should exit script execution * @var boolean */ protected $_exit = true; /** * Whether or not _redirect() should attempt to prepend the base URL to the * passed URL (if it's a relative URL) * @var boolean */ protected $_prependBase = true; /** * Url to which to redirect * @var string */ protected $_redirectUrl = null; /** * Whether or not to use an absolute URI when redirecting * @var boolean */ protected $_useAbsoluteUri = false; /** * Whether or not to close the session before exiting * @var boolean */ protected $_closeSessionOnExit = true; /** * Retrieve HTTP status code to emit on {@link _redirect()} call * * @return int */ public function getCode() { return $this->_code; } /** * Validate HTTP status redirect code * * @param int $code * @throws Zend_Controller_Action_Exception on invalid HTTP status code * @return true */ protected function _checkCode($code) { $code = (int)$code; if ((300 > $code) || (307 < $code) || (304 == $code) || (306 == $code)) { require_once 'Zend/Controller/Action/Exception.php'; throw new Zend_Controller_Action_Exception('Invalid redirect HTTP status code (' . $code . ')'); } return true; } /** * Retrieve HTTP status code for {@link _redirect()} behaviour * * @param int $code * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface */ public function setCode($code) { $this->_checkCode($code); $this->_code = $code; return $this; } /** * Retrieve flag for whether or not {@link _redirect()} will exit when finished. * * @return boolean */ public function getExit() { return $this->_exit; } /** * Retrieve exit flag for {@link _redirect()} behaviour * * @param boolean $flag * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface */ public function setExit($flag) { $this->_exit = ($flag) ? true : false; return $this; } /** * Retrieve flag for whether or not {@link _redirect()} will prepend the * base URL on relative URLs * * @return boolean */ public function getPrependBase() { return $this->_prependBase; } /** * Retrieve 'prepend base' flag for {@link _redirect()} behaviour * * @param boolean $flag * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface */ public function setPrependBase($flag) { $this->_prependBase = ($flag) ? true : false; return $this; } /** * Retrieve flag for whether or not {@link redirectAndExit()} shall close the session before * exiting. * * @return boolean */ public function getCloseSessionOnExit() { return $this->_closeSessionOnExit; } /** * Set flag for whether or not {@link redirectAndExit()} shall close the session before exiting. * * @param boolean $flag * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface */ public function setCloseSessionOnExit($flag) { $this->_closeSessionOnExit = ($flag) ? true : false; return $this; } /** * Return use absolute URI flag * * @return boolean */ public function getUseAbsoluteUri() { return $this->_useAbsoluteUri; } /** * Set use absolute URI flag * * @param boolean $flag * @return Zend_Controller_Action_Helper_Redirector Provides a fluent interface */ public function setUseAbsoluteUri($flag = true) { $this->_useAbsoluteUri = ($flag) ? true : false; return $this; } /** * Set redirect in response object * * @return void */ protected function _redirect($url) { if ($this->getUseAbsoluteUri() && !preg_match('#^(https?|ftp)://#', $url)) { $host = (isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:''); $proto = (isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=="off") ? 'https' : 'http'; $port = (isset($_SERVER['SERVER_PORT'])?$_SERVER['SERVER_PORT']:80); $uri = $proto . '://' . $host; if ((('http' == $proto) && (80 != $port)) || (('https' == $proto) && (443 != $port))) { // do not append if HTTP_HOST already contains port if (strrchr($host, ':') === false) { $uri .= ':' . $port; } } $url = $uri . '/' . ltrim($url, '/'); } $this->_redirectUrl = $url; $this->getResponse()->setRedirect($url, $this->getCode()); } /** * Retrieve currently set URL for redirect * * @return string */ public function getRedirectUrl() { return $this->_redirectUrl; } /** * Determine if the baseUrl should be prepended, and prepend if necessary * * @param string $url * @return string */ protected function _prependBase($url) { if ($this->getPrependBase()) { $request = $this->getRequest(); if ($request instanceof Zend_Controller_Request_Http) { $base = rtrim($request->getBaseUrl(), '/'); if (!empty($base) && ('/' != $base)) { $url = $base . '/' . ltrim($url, '/'); } else { $url = '/' . ltrim($url, '/'); } } } return $url; } /** * Set a redirect URL of the form /module/controller/action/params * * @param string $action * @param string $controller * @param string $module * @param array $params * @return void */ public function setGotoSimple($action, $controller = null, $module = null, array $params = array()) { $dispatcher = $this->getFrontController()->getDispatcher(); $request = $this->getRequest(); $curModule = $request->getModuleName(); $useDefaultController = false; if (null === $controller && null !== $module) { $useDefaultController = true; } if (null === $module) { $module = $curModule; } if ($module == $dispatcher->getDefaultModule()) { $module = ''; } if (null === $controller && !$useDefaultController) { $controller = $request->getControllerName(); if (empty($controller)) { $controller = $dispatcher->getDefaultControllerName(); } } $params[$request->getModuleKey()] = $module; $params[$request->getControllerKey()] = $controller; $params[$request->getActionKey()] = $action; $router = $this->getFrontController()->getRouter(); $url = $router->assemble($params, 'default', true); $this->_redirect($url); } /** * Build a URL based on a route * * @param array $urlOptions * @param string $name Route name * @param boolean $reset * @param boolean $encode * @return void */ public function setGotoRoute(array $urlOptions = array(), $name = null, $reset = false, $encode = true) { $router = $this->getFrontController()->getRouter(); $url = $router->assemble($urlOptions, $name, $reset, $encode); $this->_redirect($url); } /** * Set a redirect URL string * * By default, emits a 302 HTTP status header, prepends base URL as defined * in request object if url is relative, and halts script execution by * calling exit(). * * $options is an optional associative array that can be used to control * redirect behaviour. The available option keys are: * - exit: boolean flag indicating whether or not to halt script execution when done * - prependBase: boolean flag indicating whether or not to prepend the base URL when a relative URL is provided * - code: integer HTTP status code to use with redirect. Should be between 300 and 307. * * _redirect() sets the Location header in the response object. If you set * the exit flag to false, you can override this header later in code * execution. * * If the exit flag is true (true by default), _redirect() will write and * close the current session, if any. * * @param string $url * @param array $options * @return void */ public function setGotoUrl($url, array $options = array()) { // prevent header injections $url = str_replace(array("\n", "\r"), '', $url); if (null !== $options) { if (isset($options['exit'])) { $this->setExit(($options['exit']) ? true : false); } if (isset($options['prependBase'])) { $this->setPrependBase(($options['prependBase']) ? true : false); } if (isset($options['code'])) { $this->setCode($options['code']); } } // If relative URL, decide if we should prepend base URL if (!preg_match('|^[a-z]+://|', $url)) { $url = $this->_prependBase($url); } $this->_redirect($url); } /** * Perform a redirect to an action/controller/module with params * * @param string $action * @param string $controller * @param string $module * @param array $params * @return void */ public function gotoSimple($action, $controller = null, $module = null, array $params = array()) { $this->setGotoSimple($action, $controller, $module, $params); if ($this->getExit()) { $this->redirectAndExit(); } } /** * Perform a redirect to an action/controller/module with params, forcing an immdiate exit * * @param mixed $action * @param mixed $controller * @param mixed $module * @param array $params * @return void */ public function gotoSimpleAndExit($action, $controller = null, $module = null, array $params = array()) { $this->setGotoSimple($action, $controller, $module, $params); $this->redirectAndExit(); } /** * Redirect to a route-based URL * * Uses route's assemble method tobuild the URL; route is specified by $name; * default route is used if none provided. * * @param array $urlOptions Array of key/value pairs used to assemble URL * @param string $name * @param boolean $reset * @param boolean $encode * @return void */ public function gotoRoute(array $urlOptions = array(), $name = null, $reset = false, $encode = true) { $this->setGotoRoute($urlOptions, $name, $reset, $encode); if ($this->getExit()) { $this->redirectAndExit(); } } /** * Redirect to a route-based URL, and immediately exit * * Uses route's assemble method tobuild the URL; route is specified by $name; * default route is used if none provided. * * @param array $urlOptions Array of key/value pairs used to assemble URL * @param string $name * @param boolean $reset * @return void */ public function gotoRouteAndExit(array $urlOptions = array(), $name = null, $reset = false) { $this->setGotoRoute($urlOptions, $name, $reset); $this->redirectAndExit(); } /** * Perform a redirect to a url * * @param string $url * @param array $options * @return void */ public function gotoUrl($url, array $options = array()) { $this->setGotoUrl($url, $options); if ($this->getExit()) { $this->redirectAndExit(); } } /** * Set a URL string for a redirect, perform redirect, and immediately exit * * @param string $url * @param array $options * @return void */ public function gotoUrlAndExit($url, array $options = array()) { $this->setGotoUrl($url, $options); $this->redirectAndExit(); } /** * exit(): Perform exit for redirector * * @return void */ public function redirectAndExit() { if ($this->getCloseSessionOnExit()) { // Close session, if started if (class_exists('Zend_Session', false) && Zend_Session::isStarted()) { Zend_Session::writeClose(); } elseif (isset($_SESSION)) { session_write_close(); } } $this->getResponse()->sendHeaders(); exit(); } /** * direct(): Perform helper when called as * $this->_helper->redirector($action, $controller, $module, $params) * * @param string $action * @param string $controller * @param string $module * @param array $params * @return void */ public function direct($action, $controller = null, $module = null, array $params = array()) { $this->gotoSimple($action, $controller, $module, $params); } /** * Overloading * * Overloading for old 'goto', 'setGoto', and 'gotoAndExit' methods * * @param string $method * @param array $args * @return mixed * @throws Zend_Controller_Action_Exception for invalid methods */ public function __call($method, $args) { $method = strtolower($method); if ('goto' == $method) { return call_user_func_array(array($this, 'gotoSimple'), $args); } if ('setgoto' == $method) { return call_user_func_array(array($this, 'setGotoSimple'), $args); } if ('gotoandexit' == $method) { return call_user_func_array(array($this, 'gotoSimpleAndExit'), $args); } require_once 'Zend/Controller/Action/Exception.php'; throw new Zend_Controller_Action_Exception(sprintf('Invalid method "%s" called on redirector', $method)); } }
希望本文所述对大家PHP程序设计有所帮助。
更多Zend Framework动作助手Redirector用法实例详解相关文章请关注PHP中文网!
推荐阅读
-
Zend Framework教程之资源(Resources)用法实例详解
-
Zend Framework教程之Application用法实例详解
-
Zend Framework动作助手Redirector用法实例详解
-
Zend Framework动作助手Json用法实例分析
-
Zend Framework动作助手Url用法详解
-
Zend Framework动作助手(Zend_Controller_Action_Helper)用法详解
-
Zend Framework动作助手FlashMessenger用法详解
-
Zend Framework创建自己的动作助手详解
-
Zend Framework分页类用法详解_php实例
-
Zend Framework教程之动作的基类Zend_Controller_Action详解_php实例