5.11 共通功能——利用别名,隐藏网页真实路径
在第4章以及前几节中已经介绍过,在Zend Framework中,请求URI有着特殊的形式,例如本系统默认的请求URI的形式如下。
http://localhost/samples/chap5/default/index/list
http://localhost/samples/chap5/bm/config
这样的请求URI不仅显得长,特别是在后面再带几个Query信息后,就显得烦琐。而且,当了解Zend Framework技术的人看到这个请求URI时,就可以猜出module,controller,action的名称,从而能了解应用程序的结构特征。这显然不利于系统的安全,以及网站技术的保密。本节将介绍本系统的共通功能之一——利用别名,隐藏网页真实路径,解决上述的问题。
通过别名隐藏网页真实路径
要点
在本系统中可以将页面的请求URI分成两种类型:一种与具体用户无关的公共功能,另一种是与特定用户相关的页面(功能)。注意,后一种页面一部分也是可以被其他用户或客人访问的,只是信息属于特定的用户所有,当然也只有所有者才能维护这些信息。
在系统中,针对上述两种类型的请求URI,有两种不同的形式。其中第一种情况的请求URI为:http://localhost/samples/chap5/别名。
而第二种情况的请求URI为:http://localhost/samples/chap5/用户ID/别名。
别名与具体的action的一一对应信息保存在表metadata中,表5-22所示的就是其中的部分数据。
表5-22 metadata中的部分数据
※其中URI类型标示为1时,表示此网页的请求URI为第一种情况。
而上述两种类型的请求URI在表sitemenu中保存的形式是不同的,如表5-23所示。
表5-23 请求URI在表sitemenu中保存的形式
因此,针对第二种请求URI在实际生成页面URL时,需要将“myfrontuserid”转换为实际的用户ID。在5.8节的SitemapPlugin.class.php中就有上述的转换过程。本节的程序中同样会有类似的操作,后面的程序会有说明。
目录结构
数据库中的表结构
URI与网页信息对照表(metadata)参见5.8节。
代码
取出module名,以及用户ID。当请求URI为“/用户ID/别名”时,当系统根URI(http://localhost/samples/chap5/)后紧接的module名没有在index.php中注册(请参照4.16节以及5.2节),则getModuleName方法取得的值为“default”,而getControllerName方法取得就是用户ID了。后面的补充资料有详细介绍。
在用户ID为“auth”“index”“error”“about”(这些都是default模块中的controller)以外时,调用setTrueAction方法进行别名到实际action的转换。
定义别名到实际action转换的方法。带一个参数——请求对象。
取出用户ID、别名。
进行别名的检查。当请求URI为“要点”中介绍的第一种情况时,变量userid中设置的显然是别名。因此有20行的再赋值处理。
将别名保存在session变量alias中,在SitemapPlugin类会用到这个变量。
别名与网页的标题,介绍等一样经常发生修改,为提高效率将其保存在缓冲中,此处初始化缓冲对象(在5.8节中已有介绍)。
如果在缓冲中已经存在别名数组,使用load方法取出,否则在33行到34行进行从数据库取出所有别名,并利用save方法以“alias”的名称保存在缓冲中。
调用setAlias方法从数据库取出所有的别名。
定义默认action,这样如果输入的URL不合法,将统一跳转到本系统的首页。
43行进行所有者(用户ID)检查,显然如果是第一种请求URI时,不用进行这种检查。因此40行又一次调用checkAlias方法进行判断。
取得包含当前module/controller/action的数组,放置在变量$dispatch中。
如果用户ID有效,且变量$dispatc为数组时,则进行重新设置module/controller/action的工作。
将用户ID保存在sessian变量owner(所有者ID)。
定义从数据库中取出别名的方法。
从表metadata中检索所有别名列非空的数据。
循环将检索出的module/controller/action放在联想数组result中,使用$result“别名”后就可以取得对应的module/controller/action。
定义别名检查方法。参数为检查对象,检查对象是否为“要点”中介绍的第一种请求URI的别名。
检查方法很简单。首先在70行到72行取出表metadata中所有第一种请求URI的别名(即分类标示flag为1)。
对所有取出的别名进行循环。与检查对象相等时,返回TRUE(默认为FALSE),并退出循环。
补充
关于getModuleName,getControllerName,getActionName方法
getModuleName,getControllerName,getActionName方法的使用在第4章中已经有过介绍,第4章中是默认所有module都已经注册(在前台控制台index.php中)。如果出现module没有注册的情况时,getModuleName方法取得的值将始终是“default”,而getControllerName方法取得的才是紧接在该URL后那个没有注册的module名,当然后面就依次为controller名等。
上面的别名转换方法中就是利用了上述特性,请结合实际代码加深理解。