亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

Zend Framework教程之路由功能Zend_Controller_Router詳解

2024-05-04 23:43:41
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Zend Framework教程之路由功能Zend_Controller_Router,詳細分析了路由功能Zend_Controller_Router的原理,使用技巧與相關注意事項,需要的朋友可以參考下
 

本文實例講述了Zend Framework教程之路由功能Zend_Controller_Router用法。分享給大家供大家參考,具體如下:

Zend Framework的路由提供了兩個主要功能路由和創建路由。

Zend_Controller_Router的Route類和相應Route目錄下的類定義常見的路由操作。

接口Zend_Controller_Router_Interface,類Zend_Controller_Router_Abstract和Zend_Controller_Router_Rewrite完成了基本的路由,創建路由,刪除路由的功能。

└── Router
    ├── Abstract.php
    ├── Exception.php
    ├── Interface.php
    ├── Rewrite.php
    ├── Route
    │   ├── Abstract.php
    │   ├── Chain.php
    │   ├── Hostname.php
    │   ├── Interface.php
    │   ├── Module.php
    │   ├── Regex.php
    │   └── Static.php
    └── Route.php

Zend_Controller_Router路由功能的實現

Zend_Controller_Router_Interface

<?phpinterface Zend_Controller_Router_Interface{  /**   * Processes a request and sets its controller and action. If   * no route was possible, an exception is thrown.   *   * @param Zend_Controller_Request_Abstract   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Request_Abstract|boolean   */  public function route(Zend_Controller_Request_Abstract $dispatcher);  /**   * Generates a URL path that can be used in URL creation, redirection, etc.   *   * May be passed user params to override ones from URI, Request or even defaults.   * If passed parameter has a value of null, it's URL variable will be reset to   * default.   *   * If null is passed as a route name assemble will use the current Route or 'default'   * if current is not yet set.   *   * Reset is used to signal that all parameters should be reset to it's defaults.   * Ignoring all URL specified values. User specified params still get precedence.   *   * Encode tells to url encode resulting path parts.   *   * @param array $userParams Options passed by a user used to override parameters   * @param mixed $name The name of a Route to use   * @param bool $reset Whether to reset to the route defaults ignoring URL params   * @param bool $encode Tells to encode URL parts on output   * @throws Zend_Controller_Router_Exception   * @return string Resulting URL path   */  public function assemble($userParams, $name = null, $reset = false, $encode = true);  /**   * Retrieve Front Controller   *   * @return Zend_Controller_Front   */  public function getFrontController();  /**   * Set Front Controller   *   * @param Zend_Controller_Front $controller   * @return Zend_Controller_Router_Interface   */  public function setFrontController(Zend_Controller_Front $controller);  /**   * Add or modify a parameter with which to instantiate any helper objects   *   * @param string $name   * @param mixed $param   * @return Zend_Controller_Router_Interface   */  public function setParam($name, $value);  /**   * Set an array of a parameters to pass to helper object constructors   *   * @param array $params   * @return Zend_Controller_Router_Interface   */  public function setParams(array $params);  /**   * Retrieve a single parameter from the controller parameter stack   *   * @param string $name   * @return mixed   */  public function getParam($name);  /**   * Retrieve the parameters to pass to helper object constructors   *   * @return array   */  public function getParams();  /**   * Clear the controller parameter stack   *   * By default, clears all parameters. If a parameter name is given, clears   * only that parameter; if an array of parameter names is provided, clears   * each.   *   * @param null|string|array single key or array of keys for params to clear   * @return Zend_Controller_Router_Interface   */  public function clearParams($name = null);}

Zend_Controller_Router_Abstract

<?php/** Zend_Controller_Router_Interface */require_once 'Zend/Controller/Router/Interface.php';abstract class Zend_Controller_Router_Abstract implements Zend_Controller_Router_Interface{  /**   * URI delimiter   */  const URI_DELIMITER = '/';  /**   * Front controller instance   * @var Zend_Controller_Front   */  protected $_frontController;  /**   * Array of invocation parameters to use when instantiating action   * controllers   * @var array   */  protected $_invokeParams = array();  /**   * Constructor   *   * @param array $params   * @return void   */  public function __construct(array $params = array())  {    $this->setParams($params);  }  /**   * Add or modify a parameter to use when instantiating an action controller   *   * @param string $name   * @param mixed $value   * @return Zend_Controller_Router   */  public function setParam($name, $value)  {    $name = (string) $name;    $this->_invokeParams[$name] = $value;    return $this;  }  /**   * Set parameters to pass to action controller constructors   *   * @param array $params   * @return Zend_Controller_Router   */  public function setParams(array $params)  {    $this->_invokeParams = array_merge($this->_invokeParams, $params);    return $this;  }  /**   * Retrieve a single parameter from the controller parameter stack   *   * @param string $name   * @return mixed   */  public function getParam($name)  {    if(isset($this->_invokeParams[$name])) {      return $this->_invokeParams[$name];    }    return null;  }  /**   * Retrieve action controller instantiation parameters   *   * @return array   */  public function getParams()  {    return $this->_invokeParams;  }  /**   * Clear the controller parameter stack   *   * By default, clears all parameters. If a parameter name is given, clears   * only that parameter; if an array of parameter names is provided, clears   * each.   *   * @param null|string|array single key or array of keys for params to clear   * @return Zend_Controller_Router   */  public function clearParams($name = null)  {    if (null === $name) {      $this->_invokeParams = array();    } elseif (is_string($name) && isset($this->_invokeParams[$name])) {      unset($this->_invokeParams[$name]);    } elseif (is_array($name)) {      foreach ($name as $key) {        if (is_string($key) && isset($this->_invokeParams[$key])) {          unset($this->_invokeParams[$key]);        }      }    }    return $this;  }  /**   * Retrieve Front Controller   *   * @return Zend_Controller_Front   */  public function getFrontController()  {    // Used cache version if found    if (null !== $this->_frontController) {      return $this->_frontController;    }    require_once 'Zend/Controller/Front.php';    $this->_frontController = Zend_Controller_Front::getInstance();    return $this->_frontController;  }  /**   * Set Front Controller   *   * @param Zend_Controller_Front $controller   * @return Zend_Controller_Router_Interface   */  public function setFrontController(Zend_Controller_Front $controller)  {    $this->_frontController = $controller;    return $this;  }}

Zend_Controller_Router_Rewrite

<?php/** Zend_Controller_Router_Abstract */require_once 'Zend/Controller/Router/Abstract.php';/** Zend_Controller_Router_Route */require_once 'Zend/Controller/Router/Route.php';class Zend_Controller_Router_Rewrite extends Zend_Controller_Router_Abstract{  /**   * Whether or not to use default routes   *   * @var boolean   */  protected $_useDefaultRoutes = true;  /**   * Array of routes to match against   *   * @var array   */  protected $_routes = array();  /**   * Currently matched route   *   * @var Zend_Controller_Router_Route_Interface   */  protected $_currentRoute = null;  /**   * Global parameters given to all routes   *   * @var array   */  protected $_globalParams = array();  /**   * Separator to use with chain names   *   * @var string   */  protected $_chainNameSeparator = '-';  /**   * Determines if request parameters should be used as global parameters   * inside this router.   *   * @var boolean   */  protected $_useCurrentParamsAsGlobal = false;  /**   * Add default routes which are used to mimic basic router behaviour   *   * @return Zend_Controller_Router_Rewrite   */  public function addDefaultRoutes()  {    if (!$this->hasRoute('default')) {      $dispatcher = $this->getFrontController()->getDispatcher();      $request = $this->getFrontController()->getRequest();      require_once 'Zend/Controller/Router/Route/Module.php';      $compat = new Zend_Controller_Router_Route_Module(array(), $dispatcher, $request);      $this->_routes = array('default' => $compat) + $this->_routes;    }    return $this;  }  /**   * Add route to the route chain   *   * If route contains method setRequest(), it is initialized with a request object   *   * @param string                 $name    Name of the route   * @param Zend_Controller_Router_Route_Interface $route   Instance of the route   * @return Zend_Controller_Router_Rewrite   */  public function addRoute($name, Zend_Controller_Router_Route_Interface $route)  {    if (method_exists($route, 'setRequest')) {      $route->setRequest($this->getFrontController()->getRequest());    }    $this->_routes[$name] = $route;    return $this;  }  /**   * Add routes to the route chain   *   * @param array $routes Array of routes with names as keys and routes as values   * @return Zend_Controller_Router_Rewrite   */  public function addRoutes($routes) {    foreach ($routes as $name => $route) {      $this->addRoute($name, $route);    }    return $this;  }  /**   * Create routes out of Zend_Config configuration   *   * Example INI:   * routes.archive.route = "archive/:year/*"   * routes.archive.defaults.controller = archive   * routes.archive.defaults.action = show   * routes.archive.defaults.year = 2000   * routes.archive.reqs.year = "/d+"   *   * routes.news.type = "Zend_Controller_Router_Route_Static"   * routes.news.route = "news"   * routes.news.defaults.controller = "news"   * routes.news.defaults.action = "list"   *   * And finally after you have created a Zend_Config with above ini:   * $router = new Zend_Controller_Router_Rewrite();   * $router->addConfig($config, 'routes');   *   * @param Zend_Config $config Configuration object   * @param string   $section Name of the config section containing route's definitions   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Router_Rewrite   */  public function addConfig(Zend_Config $config, $section = null)  {    if ($section !== null) {      if ($config->{$section} === null) {        require_once 'Zend/Controller/Router/Exception.php';        throw new Zend_Controller_Router_Exception("No route configuration in section '{$section}'");      }      $config = $config->{$section};    }    foreach ($config as $name => $info) {      $route = $this->_getRouteFromConfig($info);      if ($route instanceof Zend_Controller_Router_Route_Chain) {        if (!isset($info->chain)) {          require_once 'Zend/Controller/Router/Exception.php';          throw new Zend_Controller_Router_Exception("No chain defined");        }        if ($info->chain instanceof Zend_Config) {          $childRouteNames = $info->chain;        } else {          $childRouteNames = explode(',', $info->chain);        }        foreach ($childRouteNames as $childRouteName) {          $childRoute = $this->getRoute(trim($childRouteName));          $route->chain($childRoute);        }        $this->addRoute($name, $route);      } elseif (isset($info->chains) && $info->chains instanceof Zend_Config) {        $this->_addChainRoutesFromConfig($name, $route, $info->chains);      } else {        $this->addRoute($name, $route);      }    }    return $this;  }  /**   * Get a route frm a config instance   *   * @param Zend_Config $info   * @return Zend_Controller_Router_Route_Interface   */  protected function _getRouteFromConfig(Zend_Config $info)  {    $class = (isset($info->type)) ? $info->type : 'Zend_Controller_Router_Route';    if (!class_exists($class)) {      require_once 'Zend/Loader.php';      Zend_Loader::loadClass($class);    }    $route = call_user_func(array($class, 'getInstance'), $info);    if (isset($info->abstract) && $info->abstract && method_exists($route, 'isAbstract')) {      $route->isAbstract(true);    }    return $route;  }  /**   * Add chain routes from a config route   *   * @param string                 $name   * @param Zend_Controller_Router_Route_Interface $route   * @param Zend_Config              $childRoutesInfo   * @return void   */  protected function _addChainRoutesFromConfig($name,                         Zend_Controller_Router_Route_Interface $route,                         Zend_Config $childRoutesInfo)  {    foreach ($childRoutesInfo as $childRouteName => $childRouteInfo) {      if (is_string($childRouteInfo)) {        $childRouteName = $childRouteInfo;        $childRoute   = $this->getRoute($childRouteName);      } else {        $childRoute = $this->_getRouteFromConfig($childRouteInfo);      }      if ($route instanceof Zend_Controller_Router_Route_Chain) {        $chainRoute = clone $route;        $chainRoute->chain($childRoute);      } else {        $chainRoute = $route->chain($childRoute);      }      $chainName = $name . $this->_chainNameSeparator . $childRouteName;      if (isset($childRouteInfo->chains)) {        $this->_addChainRoutesFromConfig($chainName, $chainRoute, $childRouteInfo->chains);      } else {        $this->addRoute($chainName, $chainRoute);      }    }  }  /**   * Remove a route from the route chain   *   * @param string $name Name of the route   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Router_Rewrite   */  public function removeRoute($name)  {    if (!isset($this->_routes[$name])) {      require_once 'Zend/Controller/Router/Exception.php';      throw new Zend_Controller_Router_Exception("Route $name is not defined");    }    unset($this->_routes[$name]);    return $this;  }  /**   * Remove all standard default routes   *   * @param Zend_Controller_Router_Route_Interface Route   * @return Zend_Controller_Router_Rewrite   */  public function removeDefaultRoutes()  {    $this->_useDefaultRoutes = false;    return $this;  }  /**   * Check if named route exists   *   * @param string $name Name of the route   * @return boolean   */  public function hasRoute($name)  {    return isset($this->_routes[$name]);  }  /**   * Retrieve a named route   *   * @param string $name Name of the route   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Router_Route_Interface Route object   */  public function getRoute($name)  {    if (!isset($this->_routes[$name])) {      require_once 'Zend/Controller/Router/Exception.php';      throw new Zend_Controller_Router_Exception("Route $name is not defined");    }    return $this->_routes[$name];  }  /**   * Retrieve a currently matched route   *   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Router_Route_Interface Route object   */  public function getCurrentRoute()  {    if (!isset($this->_currentRoute)) {      require_once 'Zend/Controller/Router/Exception.php';      throw new Zend_Controller_Router_Exception("Current route is not defined");    }    return $this->getRoute($this->_currentRoute);  }  /**   * Retrieve a name of currently matched route   *   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Router_Route_Interface Route object   */  public function getCurrentRouteName()  {    if (!isset($this->_currentRoute)) {      require_once 'Zend/Controller/Router/Exception.php';      throw new Zend_Controller_Router_Exception("Current route is not defined");    }    return $this->_currentRoute;  }  /**   * Retrieve an array of routes added to the route chain   *   * @return array All of the defined routes   */  public function getRoutes()  {    return $this->_routes;  }  /**   * Find a matching route to the current PATH_INFO and inject   * returning values to the Request object.   *   * @throws Zend_Controller_Router_Exception   * @return Zend_Controller_Request_Abstract Request object   */  public function route(Zend_Controller_Request_Abstract $request)  {    if (!$request instanceof Zend_Controller_Request_Http) {      require_once 'Zend/Controller/Router/Exception.php';      throw new Zend_Controller_Router_Exception('Zend_Controller_Router_Rewrite requires a Zend_Controller_Request_Http-based request object');    }    if ($this->_useDefaultRoutes) {      $this->addDefaultRoutes();    }    // Find the matching route    $routeMatched = false;    foreach (array_reverse($this->_routes, true) as $name => $route) {      // TODO: Should be an interface method. Hack for 1.0 BC      if (method_exists($route, 'isAbstract') && $route->isAbstract()) {        continue;      }      // TODO: Should be an interface method. Hack for 1.0 BC      if (!method_exists($route, 'getVersion') || $route->getVersion() == 1) {        $match = $request->getPathInfo();      } else {        $match = $request;      }      if ($params = $route->match($match)) {        $this->_setRequestParams($request, $params);        $this->_currentRoute = $name;        $routeMatched    = true;        break;      }    }     if (!$routeMatched) {       require_once 'Zend/Controller/Router/Exception.php';       throw new Zend_Controller_Router_Exception('No route matched the request', 404);     }    if($this->_useCurrentParamsAsGlobal) {      $params = $request->getParams();      foreach($params as $param => $value) {        $this->setGlobalParam($param, $value);      }    }    return $request;  }  protected function _setRequestParams($request, $params)  {    foreach ($params as $param => $value) {      $request->setParam($param, $value);      if ($param === $request->getModuleKey()) {        $request->setModuleName($value);      }      if ($param === $request->getControllerKey()) {        $request->setControllerName($value);      }      if ($param === $request->getActionKey()) {        $request->setActionName($value);      }    }  }  /**   * Generates a URL path that can be used in URL creation, redirection, etc.   *   * @param array $userParams Options passed by a user used to override parameters   * @param mixed $name The name of a Route to use   * @param bool $reset Whether to reset to the route defaults ignoring URL params   * @param bool $encode Tells to encode URL parts on output   * @throws Zend_Controller_Router_Exception   * @return string Resulting absolute URL path   */  public function assemble($userParams, $name = null, $reset = false, $encode = true)  {    if (!is_array($userParams)) {      require_once 'Zend/Controller/Router/Exception.php';      throw new Zend_Controller_Router_Exception('userParams must be an array');    }    if ($name == null) {      try {        $name = $this->getCurrentRouteName();      } catch (Zend_Controller_Router_Exception $e) {        $name = 'default';      }    }    // Use UNION (+) in order to preserve numeric keys    $params = $userParams + $this->_globalParams;    $route = $this->getRoute($name);    $url  = $route->assemble($params, $reset, $encode);    if (!preg_match('|^[a-z]+://|', $url)) {      $url = rtrim($this->getFrontController()->getBaseUrl(), self::URI_DELIMITER) . self::URI_DELIMITER . $url;    }    return $url;  }  /**   * Set a global parameter   *   * @param string $name   * @param mixed $value   * @return Zend_Controller_Router_Rewrite   */  public function setGlobalParam($name, $value)  {    $this->_globalParams[$name] = $value;    return $this;  }  /**   * Set the separator to use with chain names   *   * @param string $separator The separator to use   * @return Zend_Controller_Router_Rewrite   */  public function setChainNameSeparator($separator) {    $this->_chainNameSeparator = $separator;    return $this;  }  /**   * Get the separator to use for chain names   *   * @return string   */  public function getChainNameSeparator() {    return $this->_chainNameSeparator;  }  /**   * Determines/returns whether to use the request parameters as global parameters.   *   * @param boolean|null $use   *      Null/unset when you want to retrieve the current state.   *      True when request parameters should be global, false otherwise   * @return boolean|Zend_Controller_Router_Rewrite   *       Returns a boolean if first param isn't set, returns an   *       instance of Zend_Controller_Router_Rewrite otherwise.   *   */  public function useRequestParametersAsGlobal($use = null) {    if($use === null) {      return $this->_useCurrentParamsAsGlobal;    }    $this->_useCurrentParamsAsGlobal = (bool) $use;    return $this;  }}

添加路由的操作方法

public function addRoute($name, Zend_Controller_Router_Route_Interface $route)
public function addRoutes($routes)

$router = $ctrl->getRouter(); // returns a rewrite router by default$router->addRoute('user',         new Zend_Controller_Router_Route('user/:username'));

addRoute的第一個參數是路由名。第二個參數是路由自己。路由名最普通的用法是通過Zend_View_Url助手的方法:

"<?= $this->url(array('username' => 'martel'), 'user') ?>">Martel</a>

它將導致在 href: user/martel.

路由是一個簡單的過程,這個過程通過所有提供的路由和匹配它的當前請求的URI定義來迭代。當一個正匹配被發現,變量值從路由實例返回并注入到Zend_Controller_Request對象以備將來在派遣器和用戶創建的控制器中使用。如果是負匹配,在鏈中的下個路由被檢查。

Note: 倒序匹配

用倒序來匹配路由確保最通用的路由被首先定義。

Note: 返回的值

從路由返回的值來自于URL參數或用于定義的缺省值。這些變量以后可通過Zend_Controller_Request::getParam() 或 Zend_Controller_Action::_getParam() 方法來訪問。

有三個特殊的變量可用于你的路由-'module'、 'controller' 和 'action'。這些特殊的變量被Zend_Controller_Dispatcher用來找出控制器和動作然后派遣過去。

Note: 特殊變量

如果你選擇通過 setControllerKey 和 setActionKey方法的方式來改變缺省值,這些特殊變量的名字可能會不同。

缺省路由

Zend_Controller_Router_Rewrite 和缺省路由一起預先配置,它將以controller/action的形式匹配URIs。另外,模塊名可以被指定作為第一個路徑參數,允許這種module/controller/action形式的URIs。最后,它也將缺省地匹配任何另外的追加到URI的參數-controller/action/var1/value1/var2/value2。

一些路由如何匹配的例子:

// Assuming the following:$ctrl->setControllerDirectory(  array(    'default' => '/path/to/default/controllers',    'news'  => '/path/to/news/controllers',    'blog'  => '/path/to/blog/controllers'  ));Module only:http://example/news  module == newsInvalid module maps to controller name:http://example/foo  controller == fooModule + controller:http://example/blog/archive  module   == blog  controller == archiveModule + controller + action:http://example/blog/archive/list  module   == blog  controller == archive  action   == listModule + controller + action + params:http://example/blog/archive/list/sort/alpha/date/desc  module   == blog  controller == archive  action   == list  sort    == alpha  date    == desc

缺省路由是存儲在RewriteRouter名(index)為'default'的簡單的Zend_Controller_Router_Route_Module對象。它被創建多多少少象下面這樣:

$compat = new Zend_Controller_Router_Route_Module(array(),                         $dispatcher,                         $request);$this->addRoute('default', $compat);

如果你不想這個特別的缺省路由在你的路由計劃中,你可以重寫你自己的‘缺省'路由(例如,把它存儲在'default'名下)或用removeDefaultRoutes()完全清除它:

// Remove any default routes$router->removeDefaultRoutes();

為了增加路由的靈活性,方便自定義新的路由類型,Zend_Controller_Router定義了Zend_Controller_Router_Route_Interface接口和類Zend_Controller_Router_Route_Abstract,實現相應的類方法即可定義路由類型,為開發提供了便利。

Zend_Controller_Router的路由類型

Zend_Controller_Router默認提供了以下路由類型,分別為:

Zend_Controller_Router_Route
Zend_Controller_Router_Route_Static
Zend_Controller_Router_Route_Regex
Zend_Controller_Router_Route_Hostname
Zend_Controller_Router_Route_Module
Zend_Controller_Router_Route_Chain
Zend_Controller_Router_Route

Zend_Controller_Router_Route是標準的框架路由。它結合了靈活路由定義的易用性。每個路由包含了基本的URL映射(靜態的和動態的部分(變量))并且可以被缺省地初始化,也可以根據不同的要求初始化。

讓我們想象一下我們假設的應用程序將需要一些廣域內容作者的信息頁面。我們想能夠把瀏覽器指向http://domain.com/author/martel去看一個叫"martel"的信息。有這樣功能的路由看起來是這樣的:

$route = new Zend_Controller_Router_Route(  'author/:username',  array(    'controller' => 'profile',    'action'   => 'userinfo'  ));$router->addRoute('user', $route);

在Zend_Controller_Router_Route里構造函數的第一個參數是路由的定義,它將匹配一個URL。路由定義包含靜態的和動態部分,它們由正斜杠('/')符分開。靜態部分只是簡單的字符:author。動態部分,被叫做變量,用預設的冒號來標記變量名::username。

Note: 字符的的用法

當前的實現允許你使用任何字符(正斜杠除外)作為變量標識符,但強烈建議只使用PHP使用的變量標識符。將來的實現也許會改變這個行為,它可能會導致在你的代碼里有隱藏的bugs。

當你把瀏覽器指向http://domain.com/author/martel這個例子的路由應該被匹配,它所有的變量將被注入到Zend_Controller_Request對象并在ProfileController可訪問。由這個例子返回的變量可能會被表示為如下鍵和值配對的數組:

$values = array(  'username'  => 'martel',  'controller' => 'profile',  'action'   => 'userinfo');

稍后,基于這些值,Zend_Controller_Dispatcher_Standard應該調用ProfileController類(在缺省模塊中)中的userinfoAction()方法。你將依靠Zend_Controller_Action::_getParam()或者Zend_Controller_Request::getParam()方法能夠訪問所有的變量:

public function userinfoAction(){  $request = $this->getRequest();  $username = $request->getParam('username');  $username = $this->_getParam('username');}

路由定義可以包一個額外的特別字符-通配符-表示為'*'號。它被用來取得參數,和缺省模塊路由類似(在URI中定義的var=>value)。下面的路由多多少少地模仿了模塊路由的行為:

$route = new Zend_Controller_Router_Route(  ':module/:controller/:action/*',  array('module' => 'default'));$router->addRoute('default', $route);

變量缺省

在路由中每個變量可以有一個缺省值,這就是Zend_Controller_Router_Route中構造函數使用的第二個變量。這個參數是一個數組,在數組中鍵表示變量名,值就是期望的缺省值:

$route = new Zend_Controller_Router_Route(  'archive/:year',  array('year' => 2006));$router->addRoute('archive', $route);

上述路由將匹配象http://domain.com/archive/2005和http://example.com/archive的URLs。對于后者變量year將有一個初始的缺省值為2006。

這個例子將導致注入一個year變量給請求對象。應為沒有路由信息出現(沒有控制器和動作參數被定義),應用程序將被派遣給缺省的控制器和動作方法(它們都在Zend_Controller_Dispatcher_Abstract被定義)。為使它更可用,你必須提供一個有效的控制器和動作作為路由的缺省值:

$route = new Zend_Controller_Router_Route(  'archive/:year',  array(    'year'    => 2006,    'controller' => 'archive',    'action'   => 'show'  ));$router->addRoute('archive', $route);

這個路由將導致派遣給ArchiveController類的showAction()方法。

變量請求

當變量請求被設定,第三個參數可以加給Zend_Controller_Router_Route的構造函數。這些被定義為正則表達式的一部分:

$route = new Zend_Controller_Router_Route(  'archive/:year',  array(    'year'    => 2006,    'controller' => 'archive',    'action'   => 'show'  ),  array('year' => '/d+'));$router->addRoute('archive', $route);

用上述定義的路由,路由器僅當year變量包含數字數據將匹配它,例如http://domain.com/archive/2345。象http://example.com/archive/test這樣的URL將不被匹配并且控制將被傳遞給在鏈中的下一個路由。

主機名路由

你也可以使用主機名做路由匹配。對簡單的匹配使用靜態主機名選項:

$route = new Zend_Controller_Router_Route(  array(    'host' => 'blog.mysite.com',    'path' => 'archive'  ),  array(    'module'   => 'blog',    'controller' => 'archive',    'action'   => 'index'  ));$router->addRoute('archive', $route);

如果你想匹配參數在主機名里,使用 regex 選項。在下面例子中,子域為動作控制器被用作用戶名參數。 當組裝路由時,你可以給出用戶名為參數,就像你用其它路徑參數一樣:

$route = new Zend_Controller_Router_Route(  array(    'host' => array(      'regex'  => '([a-z]+).mysite.com',      'reverse' => '%s.mysite.com'      'params' => array(        1 => 'username'      )    ),    'path' => ''  ),  array(    'module'   => 'users',    'controller' => 'profile',    'action'   => 'index'  ));$router->addRoute('profile', $route);

Zend_Controller_Router_Route_Static

設置固定不變的路由:

$route = new Zend_Controller_Router_Route_Static(  'login',  array('controller' => 'auth', 'action' => 'login'));$router->addRoute('login', $route);

上面的路由將匹配http://domain.com/login的URL,并分派到 AuthController::loginAction().

Zend_Controller_Router_Route_Regex

除了缺省的和靜態的路由類型外,正則表達式路由類型也可用。這個路由比其它路由更強更靈活,只是稍微有點復雜。同時,它應該比標準路由快。

象標準路由一樣,這個路由必須用路由定義和一些缺省條件來初始化。讓我們創建一個archive路由作為例子,和先前定義的類似,這次只是用了Regex:

$route = new Zend_Controller_Router_Route_Regex(  'archive/(/d+)',  array(    'controller' => 'archive',    'action'   => 'show'  ));$router->addRoute('archive', $route);

每個定義的regex子模式將被注入到請求對象里。同上述的例子,再成功匹配http://domain.com/archive/2006之后,結果值的數組看起來象這樣:

$values = array(  1      => '2006',  'controller' => 'archive',  'action'   => 'show');

Note: 在匹配之前,開頭和結尾的斜杠從路由器里的URL中去除掉了。結果,匹配http://domain.com/foo/bar/,需要foo/bar這樣的regex,而不是/foo/bar。

Note: 行開頭和行結尾符號(分別為'^' 和 '$')被自動預先追加到所有表達式。這樣,你不需要在你的正則表達式里用它們,你應該匹配整個字符串。

Note: 這個路由類使用#符作為分隔符。這意味著你將需要避免哈希符('#')但不是正斜杠('/')在你的路由定義里。因為'#'符(名稱為錨)很少被傳給webserver,你將幾乎不需要在你的regex里使用它。

你可以用通常的辦法獲得已定義的子模式的內容:

public function showAction(){  $request = $this->getRequest();  $year  = $request->getParam(1); // $year = '2006';}

Note: 注意這個鍵是整數(1) 而不是字符串('1')。

因為'year'的缺省沒有設置,這個路由將和它的標準路由副本不是非常精確地相同。即使我們為'year'聲明一個缺省并使子模式可選,也不清楚是否會在拖尾斜杠(trailing slash)上還將有問題。方案是使整個'year'部分和斜杠一起可選但只抓取數字部分:(這段比較繞口,請校對者仔細看看,謝謝 Jason Qi)

$route = new Zend_Controller_Router_Route_Regex(  'archive(?:/(/d+))?',  array(    1      => '2006',    'controller' => 'archive',    'action'   => 'show'  ));$router->addRoute('archive', $route);

讓我們看看你可能注意到的問題。 給參數使用基于整數的鍵不是容易管理的辦法,今后可能會有問題。這就是為什么有第三個參數。這是個聯合數組表示一個regex子模式到參數名鍵的映射。我們來看看一個簡單的例子:

$route = new Zend_Controller_Router_Route_Regex(  'archive/(/d+)',  array(    'controller' => 'archive',    'action' => 'show'  ),  array(    1 => 'year'  ));$router->addRoute('archive', $route);

這將導致下面的值被注入到請求:

$values = array(  'year'    => '2006',  'controller' => 'archive',  'action'   => 'show');

這個映射被任何目錄來定義使它能工作于任何環境。鍵可以包含變量名或子模式索引:

$route = new Zend_Controller_Router_Route_Regex(  'archive/(/d+)',  array( ... ),  array(1 => 'year'));// OR$route = new Zend_Controller_Router_Route_Regex(  'archive/(/d+)',  array( ... ),  array('year' => 1));

Note: 子模式鍵必須用整數表示。

注意在請求值中的數字索引不見了,代替的是一個名字變量。當然如果你愿意可以把數字和名字變量混合使用

$route = new Zend_Controller_Router_Route_Regex(  'archive/(/d+)/page/(/d+)',  array( ... ),  array('year' => 1));

這將導致在請求中有混合的值可用。例如:URLhttp://domain.com/archive/2006/page/10將在下列結果中:

$values = array(  'year'    => '2006',  2      => 10,  'controller' => 'archive',  'action'   => 'show');

因為regex模型不容易顛倒,如果你想用URL助手或這個類中的 assemble方法,你需要準備一個顛倒的URL。這個顛倒的路徑用可由sprintf()解析的字符串來表示并定義為第四個構造參數:

$route = new Zend_Controller_Router_Route_Regex(  'archive/(/d+)',  array( ... ),  array('year' => 1),  'archive/%s');

所有這些都已經可能由標準路由對象完成,那么使用Regex路由的好處在哪里?首先,它允許你不受限制地描述任何類型的URL。想象一下你有一個博客并希望創建象http://domain.com/blog/archive/01-Using_the_Regex_Router.html這樣的URLs,還有把解析它路徑元素中的最后部分,01-Using_the_Regex_Router.html,到一個文章的ID和文章的標題/描述;這不可能由標準路由完成。用Regex路由,你可以做象下面的方案:

$route = new Zend_Controller_Router_Route_Regex(  'blog/archive/(/d+)-(.+)/.html',  array(    'controller' => 'blog',    'action'   => 'view'  ),  array(    1 => 'id',    2 => 'description'  ),  'blog/archive/%d-%s.html');$router->addRoute('blogArchive', $route);

正如你所看到的,這個在標準路由上添加了巨大的靈活性。

通過配置文件定義路由規則

例如

[production]routes.archive.route = "archive/:year/*"routes.archive.defaults.controller = archiveroutes.archive.defaults.action = showroutes.archive.defaults.year = 2000routes.archive.reqs.year = "/d+"routes.news.type = "Zend_Controller_Router_Route_Static"routes.news.route = "news"routes.news.defaults.controller = "news"routes.news.defaults.action = "list"routes.archive.type = "Zend_Controller_Router_Route_Regex"routes.archive.route = "archive/(/d+)"routes.archive.defaults.controller = "archive"routes.archive.defaults.action = "show"routes.archive.map.1 = "year"; OR: routes.archive.map.year = 1

上述的INI文件可以被讀進Zend_Config對象:

$config = new Zend_Config_Ini('/path/to/config.ini', 'production');$router = new Zend_Controller_Router_Rewrite();$router->addConfig($config, 'routes');

在上面的例子中,我們告訴路由器去使用INI文件'routes'一節給它的路由。每個在這個節下的頂級鍵將用來定義路由名;上述例子定義了路由'archive'和'news'。每個路由接著要求,至少,一個'route'條目和一個或更多'defaults'條目;可選地,一個或更多'reqs'('required'的簡寫)可能要求提供??傊@些相對應的三個參數提供給Zend_Controller_Router_Route_Interface對象。一個選項鍵,'type',可用來指定路由類的類型給特殊的路由;缺省地,它使用Zend_Controller_Router_Route。在上述例子中,'news'路由被定義來使用Zend_Controller_Router_Route_Static。

自定義路由類型

標準的rewrite路由器應當最大限度提供你所需的功能;大多時候,為了通過已知的路由提供新的或修改的功能,你將只需要創建一個新的路由類型

那就是說,你可能想要用不同的路由范例。接口Zend_Controller_Router_Interface提供了需要最少的信息來創建路由器,并包含一個單個的方法。

interface Zend_Controller_Router_Interface{ /**  * @param Zend_Controller_Request_Abstract $request  * @throws Zend_Controller_Router_Exception  * @return Zend_Controller_Request_Abstract  */ public function route(Zend_Controller_Request_Abstract $request);}

路由只發生一次:當請求第一次接收到系統。路由器的意圖是基于請求的環境決定控制器、動作和可選的參數,并把它們發給請求。請求對象接著傳遞給派遣器。如果不可能映射一個路由到一個派遣令牌,路由器對請求對象就什么也不做。



注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97视频在线观看播放| 国产成人精品a视频一区www| 成人日韩在线电影| 国产日本欧美视频| 国产精品久久久久久久久免费| 亚洲国产高清高潮精品美女| 国产精品第2页| 中文字幕亚洲欧美日韩高清| 亚洲sss综合天堂久久| 欧美精品久久久久久久久久| 欧美日韩在线观看视频小说| 亚洲精品av在线播放| 国产精品第二页| 91久久在线视频| 最新国产精品亚洲| 国产精品久久久久久久久久ktv| 91香蕉国产在线观看| 国产精品视频久久久久| 亚洲网站视频福利| 欧美日本精品在线| 亚洲欧美日韩在线高清直播| 97在线视频免费观看| 午夜精品蜜臀一区二区三区免费| 91免费视频国产| 国产成人精品免费久久久久| 国产精品免费久久久久影院| 色综久久综合桃花网| 欧美大片免费看| 色综合久久中文字幕综合网小说| 78m国产成人精品视频| 国产精品免费视频久久久| 欧美精品videosex极品1| 在线精品高清中文字幕| 中文亚洲视频在线| 久久乐国产精品| 成人激情视频免费在线| 中文字幕欧美日韩va免费视频| 中文字幕九色91在线| 欧美在线视频网站| 一区二区三区国产视频| 国产精品手机播放| 97超碰国产精品女人人人爽| 欧美午夜激情小视频| 7m精品福利视频导航| 成人av在线天堂| 欧美成人精品不卡视频在线观看| 国产精品久久久久av| 欧美一区三区三区高中清蜜桃| 日韩一区二区久久久| 97福利一区二区| 欧美日韩亚洲成人| 欧美一区二粉嫩精品国产一线天| 亚洲人成电影网站色| 日本午夜精品理论片a级appf发布| 一区二区三区天堂av| 亚洲一区二区三区视频播放| 日本久久中文字幕| 亚洲国产精品中文| 国产欧美中文字幕| 欧美激情第三页| 精品亚洲aⅴ在线观看| 中文字幕亚洲自拍| 亚洲黄色免费三级| 欧美大片欧美激情性色a∨久久| 国产在线a不卡| 姬川优奈aav一区二区| 疯狂做受xxxx欧美肥白少妇| 国产欧亚日韩视频| 久久精品国产91精品亚洲| 日韩电影在线观看中文字幕| 亚洲美女在线视频| 亚洲天堂av在线免费| 国产精品极品尤物在线观看| 久久全球大尺度高清视频| 久久99热精品这里久久精品| 欧美日韩国产成人高清视频| 久久深夜福利免费观看| 日本欧美中文字幕| 日韩在线观看网址| 亚洲成人黄色在线| 久久伊人91精品综合网站| 岛国视频午夜一区免费在线观看| 成人网页在线免费观看| 国产精品99导航| 91在线观看欧美日韩| 国产精品视频yy9099| 日韩av一区二区在线| 亚洲图片欧美日产| 亚洲欧美日韩中文在线制服| 久久久久久久97| 精品国产成人av| 国产精品久久久久久久7电影| 亚洲欧美日韩一区在线| 国产精品 欧美在线| 日韩视频永久免费观看| 一区二区三区高清国产| 精品国产一区二区在线| 欧美激情国产日韩精品一区18| 欧美性69xxxx肥| 国产精品亚洲第一区| 国产亚洲精品久久久久久777| 在线观看日韩视频| 国产97在线视频| 亚洲免费电影一区| 91精品国产99久久久久久| 欧美专区在线播放| 懂色av影视一区二区三区| 久久人91精品久久久久久不卡| 91在线网站视频| 亚洲一区制服诱惑| 亚洲free嫩bbb| 日韩一区在线视频| 97久久精品视频| 日韩精品一二三四区| 国产视频精品xxxx| 亚洲美女视频网站| 大胆欧美人体视频| 欧美亚洲国产另类| 成人高h视频在线| 精品国产乱码久久久久久婷婷| 18一19gay欧美视频网站| 亚洲男人av电影| 18性欧美xxxⅹ性满足| 久久久国产精品一区| 黄色成人av网| 欧美日韩国产一区在线| 亚洲精品suv精品一区二区| 欧美有码在线观看| 欧美黑人一级爽快片淫片高清| 国产精品美腿一区在线看| 国产欧美日韩中文字幕| 国内精品400部情侣激情| 91在线视频一区| 91精品国产自产在线观看永久| 久久精品人人做人人爽| 性色av一区二区三区| 成人免费直播live| 国产一区二区三区直播精品电影| 国产一区二区三区在线观看视频| 亚洲欧美精品在线| 亚洲电影免费观看| 日韩一区视频在线| 亚洲第一免费播放区| 国产suv精品一区二区| 欧美中文字幕视频在线观看| 色妞在线综合亚洲欧美| 成人免费午夜电影| 久久免费视频这里只有精品| 91国产视频在线播放| 欧美在线观看日本一区| 亚洲性xxxx| 欧美亚洲在线视频| 亚洲经典中文字幕| 久久视频在线免费观看| 国产精品吊钟奶在线| 国产视频欧美视频| 亚洲自拍偷拍色图| 亚洲欧美一区二区三区在线| 在线观看欧美日韩国产| 国产在线98福利播放视频| 国产精品亚洲网站| 欧美天堂在线观看| 国产婷婷97碰碰久久人人蜜臀| 国产成人精品999|