标准路由器
简介
Zend_Controller_Router_Rewrite是标准的框架路由器。路由是个过程,在这个过程中它取出URI的端点(跟着基本URL的URI的那部分)并把它分解成参数来决定哪个模块、哪个控制器和控制器中的哪个动作应该接受请求。模块、控制器、动作和其它参数被打包到Zend_Controller_Request_Http对象,接着这个对象由Zend_Controller_Dispatcher_Standard来处理。路由只发生一次:当请求最初被接收和第一个控制器被派遣之前。
Zend_Controller_Router_Rewrite被设计来考虑使用纯php结构时mod_rewrite-like的功能性。它非常宽松地基于Ruby on Rails并且不要求任何先前的web服务器URL rewriting的知识。它被设计来和单个Apache的 mod_rewrite规则(其中之一)一起工作:
或者:
如果Isapi_Rewrite已经用下列的rewrite规则被安装为一个Isapi扩展, rewrite路由器也可以和IIS web服务器一起使用:
IIS Isapi_Rewrite
当使用IIS,$_SERVER['REQUEST_URI']将要么不存在,要么被设置成一个空串。在这个例子中,Zend_Controller_Request_Http将企图使用被Isapi_Rewrite扩展设置的$_SERVER['HTTP_X_REWRITE_URL']的值。
如果使用 Lighttpd,下面的 rewrite 规则有效:
"/index.php?$1",
".*\.(js|ico|gif|jpg|png|css)$" => "$0",
"" => "/index.php"
)
]]>
使用路由器
为正确使用rewrite路由器你必须初始化它,添加一些用户定义的路由并注入到控制器。下面的代码示例这个过程:
getRouter(); // returns a rewrite router by default
$router->addRoute(
'user',
new Zend_Controller_Router_Route('user/:username',
array('controller' => 'user',
'action' => 'info'))
);
]]>
基本的Rewrite路由器操作
RewriteRouter的核心是用户定义路由的定义。路由通过调用RewriteRouter的addRoute方法和传递一个由类实现的Zend_Controller_Router_Route_Interface的新的实例被添加。例如:
addRoute('user',
new Zend_Controller_Router_Route('user/:username'));
]]>
Rewrite 路由器带有四个基本类型的路由(其中一个是特殊的):
*
路由可以被使用无数次来创建链或用户定义的应用程序路由计划。你可以在任何配置中使用任何数量的路由,除了模块路由以外,它最好被用一次并作为通用路由(例如,作为缺省的)。每个路由将在稍后详细描述。
addRoute的第一个参数是路由名。它用来作为权柄从路由器中取得路由(例如,for URL generation purposes)。第二个参数是路由自己。
路由名最普通的用法是通过Zend_View_url助手的方法:
url(array('username' => 'martel'), 'user') ?>">Martel
]]>
它将导致在 href: user/martel.
路由是一个简单的过程,这个过程通过所有提供的路由和匹配它的当前请求的URI定义来迭代。当一个正匹配被发现,变量值从路由实例返回并注入到Zend_Controller_Request对象以备将来在派遣器和用户创建的控制器中使用。如果是负匹配,在链中的下个路由被检查。
倒序匹配
用倒序来匹配路由确保最通用的路由被首先定义。
返回的值
从路由返回的值来自于URL参数或用于定义的缺省值。这些变量以后可通过Zend_Controller_Request::getParam() 或 Zend_Controller_Action::_getParam() 方法来访问。
有三个特殊的变量可用于你的路由-'module'、 'controller' 和 'action'。这些特殊的变量被Zend_Controller_Dispatcher用来找出控制器和动作然后派遣过去。
特殊变量
如果你选择通过 setControllerKey 和 setActionKey方法的方式来改变缺省值,这些特殊变量的名字可能会不同。
缺省路由
Zend_Controller_Router_Rewrite 和缺省路由一起预先配置,它将以controller/action的形式匹配URIs。另外,模块名可以被指定作为第一个路径参数,允许这种module/controller/action形式的URIs。最后,它也将缺省地匹配任何另外的追加到URI的参数-controller/action/var1/value1/var2/value2。
一些路由如何匹配的例子:
setControllerDirectory(
array(
'default' => '/path/to/default/controllers',
'news' => '/path/to/news/controllers',
'blog' => '/path/to/blog/controllers'
)
);
Module only:
http://example/news
module == news
Invalid module maps to controller name:
http://example/foo
controller == foo
Module + controller:
http://example/blog/archive
module == blog
controller == archive
Module + controller + action:
http://example/blog/archive/list
module == blog
controller == archive
action == list
Module + 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对象。它被创建多多少少象下面这样:
addRoute('default', $compat);
]]>
如果你不想这个特别的缺省路由在你的路由计划中,你可以重写你自己的‘缺省’路由(例如,把它存储在'default'名下)或用removeDefaultRoutes()完全清除它:
removeDefaultRoutes();
]]>
基本 URL 和子目录
rewrite路由器可以被用在子目录(例如,http://domain.com/~user/application-root/),在此例中,应用程序 (/~user/application-root)的基本URL应该能自动被Zend_Controller_Request_Http检测到并使用。
如果基本URL被误删除,你可以通过Zend_Controller_Request_Http 和调用 setBaseUrl() 方法(参见)用你自己的基本路径重写它。
setBaseUrl('/~user/application-root/');
]]>
Route Types
使用 Zend_Config with the RewriteRouter
有时候,用新路由更新配置文件比修改代码更方便。这个可能通过addConfig()方法来做。基本上,你创建一个Zend_Config-compatible配置,并在你的代码中读入然后传递给RewriteRouter。
作为例子,考虑下面的 INI 文件:
上述的INI文件可以被读进Zend_Config对象:
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。
Subclassing the Router
标准的rewrite路由器应当最大限度提供你所需的功能;大多时候,为了通过已知的路由提供新的或修改的功能,你将只需要创建一个新的路由类型
那就是说,你可能想要用不同的路由范例。接口Zend_Controller_Router_Interface提供了需要最少的信息来创建路由器,并包含一个单个的方法。
路由只发生一次:当请求第一次接收到系统。路由器的意图是基于请求的环境决定控制器、动作和可选的参数,并把它们发给请求。请求对象接着传递给派遣器。如果不可能映射一个路由到一个派遣令牌,路由器对请求对象就什么也不做。