一 什么是路由

  路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的过程.

  **这是TCP/IP协议第三层网络层的概念.routing and switching ,cisco,TCP/IP ,网络通信 忆往昔峥嵘岁月啊.

  引申到web开发,路由是对特定形式的URL结构进行处理的过程.for example, 从输入地址'https://www.baidu.com/index.php?tn=monline_3_dg' 到服务器返回html的过程.首先,浏览器查找自身页面缓存,cache-control,解析服务器地址,windows 不开代理的情况下,优先查找自己的host文件,然后查找系统的dns缓存,然后查找局域网dns缓存(dnslookup一会局域网交换机或者路由器会有一定的缓存,局域网的DNS服务器),然后查找ISP的dns缓存,然后顶级域名服务器查找,返回对应的A记录之后,向ip地址发出请求,请求有多种方法,GET/POST/PUT/DELETE 等,一般浏览器的请求会带上自己的头部,里面会有一些os 等字段信息,到达ip地址的服务器之后,查找对应的4层端口一般为80,这个端口的listen 的server_name,根据server 下的.htaccess和 rewrite rule 解析文件是否可以访问,php 的文件交给fast-cgi解析,fpm机制保证了性能,opcache代码缓存,如果是静态文件直接返回,脚本文件SSI之后,处理是否server端的缓存,(redis,memcahe),之后文件缓存,smarty缓存,中间还有代码缓存,解析完成返回html给请求端,请求端render html和css,JS文件由JSengine解析处理. 个人觉得这就是路由流程.可能中间还有一些其他的机制,查找querystring ,请求到服务器之后保存的地址,log,以及服务器存储,内存,硬盘读写等,往深了去想还有内存分配的字段以及垃圾回收等.(web开发真TM是个大池子啊).

  总之,路由处理的核心就是浏览器的URI指向到服务器端文件的过程.

二 路由方式

  1.正常路由.PoC index.php?action=list&id=1,2,3

  2.伪静态.  rewrite url ,htaccess PoC index.php/list/1,2,3

  3.pathinfo . 需要服务器支持,$_SERVER['pathinfo'], index.php/list/1

** 开启rewrite 功能

1 <Directory /> 
2 Options FollowSymLinks 
3 AllowOverride None 
4 </Directory>  

 

** 开启path_info

1 Options Indexes FollowSymLinks
2 AcceptPathInfo On

  $_SERVER['path_info'] 的值是脚本文件到QUERY_STRING 之间的路径部分.

  $_SERVER['REQUEST_URI'] 是URL域名之后的部分.

三 简单实现.

  指导思想: 所有请求经过伪静态的服务器规则之后,进入index.php入口文件,经过框架入口调用路由,符合路由规则的按照规则分发,不符合的正常分发.

  伪码. $_SERVER['REQUEST_URI'] 出pathinfo 和querystring;

 1 class sina_router{
 2     public function __construct(){
 3         $res = $this->_get_URI();  //取出pathinfo的信息
 4         $this->_uri_to_path($res);
 5     }
 6     public function _get_URI(){
 7 
 8         if(!isset($_SERVER['REQUEST_URI']) || !isset($_SERVER['SCRIPT_NAME'])){
 9             return '';
10         }
11         $uri = $_SERVER['REQUEST_URI'];
12 if(strpos($_SERVER['REQUEST_URI'],$_SERVER['SCRIPT_NAME'])===0){
13             $uri = substr($uri,strlen($_SERVER['SCRIPT_NAME']));
14         }
15         $patt = '/\?/';
16         $part = preg_split($patt,$uri,2);
17         $uri = $part[0];
18         if(isset($part[1])){
19             $_SERVER['QUERY_STRING'] = $part[1];
20             parse_str($_SERVER['QUERY_STRING'],$_GET);
21         }else{
22             $_SERVER['QUERY_STRING'] = $part[0];
23             $_GET = array();
24         }
25         if ($uri == '/' || empty($uri))
26         {
27             return '/';
28         }
29         $uri = parse_url($uri,PHP_URL_PATH);
30         return str_replace(array('//', '../'), '/', trim($uri, '/'));
31     }
32 
33     public function _uri_to_path($path){
34         $arr = explode('/',$path);
35         $class = array_shift($arr);
36         $method = array_shift($arr);
37         $cnt = count($arr);
38         $i=0;
39         while(($i<$cnt) && count($arr)%2===0){
40             $_GET[$arr[$i]]=$arr[$i+1];
41             $i+=2;
42         }        if(!file_exists(APP_PATH.'Controller'.DIRECTORY_SEPARATOR.$class.EXT)){
43             exit('类文件不存在');
44         }
45         require_once(APP_PATH.'Controller'.DIRECTORY_SEPARATOR.$class.EXT);
46         $obj =new $class;
47         if(!method_exists($obj,$method)){
48             exit('方法不存在!');
49         }
50         $obj->$method();
51     }
52 }

搞定.

贴下我的目录结构.

如果各位有其他实现思路,不妨留言探讨.-:)-:)-:)

posted on 2015-11-30 15:02  任城三爷  阅读(1376)  评论(0编辑  收藏  举报