sourcejoy之HDWIKI源代码分析拾遗――请求解析
我们在之前的HDWIKI源代码分析系列文章里面,对HDWIKI的请求解析这一块是一概而过的,没有详细论述,后来有朋友问我,HDWIKI的URL请求解析的问题,这篇补遗就好好研究一下这块内容,也当作对各位朋友的问题的解答吧。
首先我们先了解一下hdwiki的url请求。我们来看几个例子。
首页请求:/index.php
百科分类的请求:/index.php?category
排行榜的请求:/index.php?list
按字母浏览的请求:/index.php?list-letter-H
某个具体分类的请求:/index.php?category-view-1
随便看看的请求:/index.php?doc-random
首页右侧用户排行榜里面用户的请求:/index.php?user-space-1
登录的请求:/index.php?user-login
注册的请求:/index.php?user-register
上面列了一堆,用来观察,我们仔细观察一下这些请求的特点吧。
1)问号后面有可能有请求有可能没请求
2)每个请求各个字段用减号(-)分隔
3)有些请求具有相同的字段。比如:用户相关的请求第一个字段都是user,分类相关第一个字段都是category
我们回顾一下,在hdwiki分析系列文章的hdwiki类分析中(http://www.sourcejoy.com/php_dev/sourcejoy_hdwiki_inside.html)的时候提到过get请求。
它是在init_request方法里面初始化的,那么我们回到hdwiki类,重新看看init_request代码。掠过最开始的判断是否安装的if语句,一行行往下看。
获取了url请求里面问号后面的全部字符串:
$querystring=$_SERVER['QUERY_STRING'];
如果请求字符串里面有点(.),那么get请求就是点前面的部分,这个可能是为了为静态用的,比如点后面加上个后缀名。
$pos = strpos($querystring , '.');
if($pos!==false){
$querystring=substr($querystring,0,$pos);
}
接下来这句很关键:
$this->get = explode('-' , $querystring);
把获取的字符串,以“-”减号为分隔,各字段保存为数组。这和我们前面观察的的请求特点相吻合。
那我们根据前面的请求例子来想想$this->get 这个数组里面的元素都是什么吧。
百科分类的请求:没有减号,那么$get[0]就是category,没有其他元素啦
排行版的请求也一样:没有减号,那么$get[0]就是list,没有其他元素啦
按字母浏览的请求:$get[0]为list,$get[1]为letter,$get[2]就是H
其他请求,大家可以自己想象,$get里面的元素都是什么,很简单了。
我们继续往下看init_request代码。
if (count($this->get) <= 3 && count($_POST) == 0 && substr($querystring, 0, 6) == 'admin_' && substr($querystring, 0, 10) != 'admin_main'){
$this->querystring = $querystring;
}
这句是获取连接字符串属性的,和我们要分析的没太大关系。
接下来的三个if语句我们看看
if(empty($this->get[0])){
$this->get[0]='index';
}
if(empty($this->get[1])){
$this->get[1]='default';
}
if(count($this->get)<2){
exit(' Access Denied !');
}
第一个if是如果$get[0]为空,则把$get[0]的值设置为index
第二个if是如果$get[1]为空,则把$get[1]的值设置为defalt
第三个if是如果$get数组的元素数量少于2则退出
总结一下三个if语句就是,get数组至少要有两个元素。第一个元素默认为index,第二个元素默认为default。
我们用上面我们找到的请求例子来印证一下吧。
首页请求的时候,get数组为空,经过if语句,首页的get数组变成get[0]为index,get[1]为default。
排行榜的请求呢,只有一个元素get[0]为list,经过if语句get数组变成get[0]为list,get[1]为default。
好吧,到这里get的获取算是七七八八了。接下来我们看load_control方法。
就一个if语句,我们根据前面的请求,知道get[0]在上面几个请求中,肯定不是plugin,所以就偷懒直接看看else的内容(就是当get[0]不是plugin的时候)。
$controlfile=HDWIKI_ROOT.'/control/'.$this->get[0].'.php';
if(false===@include($controlfile)){
$this->notfound('control "'.$this->get[0].'" not found!');
}
是不是有点开窍的感觉呢?
原来get[0]设置的就是加载哪个control文件!啊哈~
我们再看看关键的run方法吧。答案很快就会揭晓啦。
第一句,很简单,把get和post作为参数实例化load_control方法里面指定的control类。
$control = new control($this->get,$this->post);
接下来的if,懒得想是干什么的。
再往下看,让我们眼前一亮的语句:
$method = 'do'.$this->get[1];
方法就是 do和get[1]组成的字符串?
我们再来根据前面请求看看这个method是什么样子
按字母浏览的请求的method就是doletter
具体分类请求的method就是doview
登录的请求就是method就是dologin
再往下,下面的if语句是判断用户登录相关的,我们不管。
再下来的if语句:
if(method_exists($control, $method))
判断control对象的指定方法是否存在,这个指定方法就是前面定义的$method
举例子,登录的请求就是判断user的control类的dologin方法是否存在
到此,我们弄懂了get[0]和get[1]的含义,一个是指定control,一个指定control的方法。
那有些请求还有第三个get元素,就是get[2]干啥的呢?
其实很简单,仔细想想就知道了,比如某个具体分类的请求,我们调用了显示某个分类的control方法,那肯定得告诉系统,调用分类的ID啦。按字母查看的请求,我们得告诉系统按照什么字符来查。
如果某个分类还要分页,那可能还涉及到了get的第四个元素了。
我们打开一个control类的源代码来印证一下我们的说法吧。
这里我们打开list的control类。看看按字母排序的method吧。
找到doletter方法:
先是判断,get的第3个元素是否为字母或者数字或者星
if(!preg_match('/^\w|\*$/i',$this->get[2]))
这就验证了我们之前的说法,提供具体参数。
接下来的代码里还出现了get[3],就是get的第四个元素。
$page = max(1, intval($this->get[3]));
看样子就知道啦。分页嘛。再次印证了我们的分析。
结论就是get的第三个元素get[2]是传给系统的具体参数,比如栏目ID,文章ID,等这些的。第四个参数在有分页的请求中就是分页参数啦。
但这里大家要注意一点,get的前两个元素是固定含义的,就是control和method,后面的参数,很可能根据请求的不同而发生改变。
我们再看个例子,打开category的control类源代码。
dodefault调用了doview方法。
就是说:百科分类栏目(/index.php?category)没有涉及具体栏目(/index.php?category-view-1)的时候也调用了doview方法。此时get的第3个元素是空的。而当调用具体栏目的时候get的第三个元素就是栏目的id。
看看doview的源代码。大家就恍然大悟了。
第一句,简单,读取分类缓存
$allcategory=$_ENV['category']->get_category_cache();
第二句开始就是if语句,判断get的第三个元素是否为数字,如果是则说明是要显示一个具体分类下的文章列表,然后一堆调用并显示。如果不是说明是在百科分类栏目(/index.php?category)中,那就是获取不同数据啦。
至此,关于hdwiki的get请求分析就结束了。相信大家对hdwiki又有了更深刻的认识。
其实,做代码分析的时候,静下心来,拨丝抽茧,步步前进。你会发觉看源代码像看一场冒险电影一样精彩和有趣的。
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:北风 来源: SourceJoy
- 标签: sourcejoy
- 发布时间:2011-09-07 23:18:15
- [72] Twitter/微博客的学习摘要
- [64] find命令的一点注意事项
- [63] Go Reflect 性能
- [62] android 开发入门
- [62] IOS安全–浅谈关于IOS加固的几种方法
- [60] 流程管理与用户研究
- [60] Oracle MTS模式下 进程地址与会话信
- [60] 如何拿下简短的域名
- [57] 图书馆的世界纪录
- [57] 【社会化设计】自我(self)部分――欢迎区