您的位置:首页 > 编程语言 > PHP开发

PHP实现一个简单url路由功能

2012-07-17 16:04 941 查看
如果一个页面的内容呈现,需要根据url上传递的参数来进行渲染。很多时候可能是这样子写:xxx.com/xx?c=x&m=x&t=..,而我们看到的url往往是这样子的(以新浪微游戏的咖啡恋人为例) game.weibo.com/ilovecoffee….这种URL设计看上去比前一种更好一点:)

如果我们访问一下不存在的游戏应用,例如game.weibo.com/ilovecoffee222,则会输出如下的错误提示:



 

game.weibo.com后面匹配到的项,指向了某个php页面,然后根据参数获取要访问的游戏应用标识,后数据库或者缓存里查询该应用标识,如果不存在则输出错误提示,如果应用存在则加载游戏应用链接地址。

 

现在写一个php例子,假设我的ip为192.168.0.33,我加了一层名为router的路径,之后跟随的是 “/模块名/方法名/参数1的key/参数1的value/….”

类似这样的地址:

192.168.0.33/router/Hello/router/a/b/c/d/abc/index.html?id=3&url=http:………………

也就是要调用Ha这个模块中的router方法,并传入url后面的参数/a/b/c/d/index………….

 

第一步,首先要在服务器的配置上对/router/路径进行拦截

 


调用某个文件夹目录下的index.php页面,假定现在所有模块使用单独的文件存放于class目录下,该目录与router平级,如下图所示:


 

 

第二步,路由分发器的实现(index.php)

[code][code] <!Doctype html>


<html>


<head>


<title>路由测试~~</title>


<meta http-equiv="content-type" content="text/html; charset=utf-8" />


</head>


<body>


 


<?php


 


date_default_timezone_set("Asia/Shanghai");


 


define("MODULE_DIR", "../class/");


 


 


$_DocumentPath = $_SERVER['DOCUMENT_ROOT'];


$_FilePath = __FILE__;


$_RequestUri = $_SERVER['REQUEST_URI'];


 


$_AppPath = str_replace($_DocumentPath, '', $_FilePath);    //==>\router\index.php


$_UrlPath = $_RequestUri;    //==>/router/hello/router/a/b/c/d/abc/index.html?id=3&url=http:


 


$_AppPathArr = explode(DIRECTORY_SEPARATOR, $_AppPath);


 


/**


* http://192.168.0.33/router/hello/router/a/b/c/d/abc/index.html?id=3&url=http:[/code] 
*


*/hello/router/a/b/c/d/abc/index.html?id=3&url=http:


*/


 


for ($i = 0; $i < count($_AppPathArr); $i++) {


$p = $_AppPathArr[$i];


if ($p) {


$_UrlPath = preg_replace('/^\/'.$p.'\//', '/', $_UrlPath, 1);


}


}


 


$_UrlPath = preg_replace('/^\//', '', $_UrlPath, 1);


 


$_AppPathArr = explode("/", $_UrlPath);


$_AppPathArr_Count = count($_AppPathArr);


 


$arr_url = array(


'controller' => 'index',


'method' => 'index',


'parms' => array()


);


 


$arr_url['controller'] = $_AppPathArr[0];


$arr_url['method'] = $_AppPathArr[1];


 


if ($_AppPathArr_Count > 2 and $_AppPathArr_Count % 2 != 0) {


die('参数错误');


} else {


for ($i = 2; $i < $_AppPathArr_Count; $i += 2) {


$arr_temp_hash = array(strtolower($_AppPathArr[$i])=>$_AppPathArr[$i + 1]);


$arr_url['parms'] = array_merge($arr_url['parms'], $arr_temp_hash);


}


}


 


$module_name = $arr_url['controller'];


$module_file = MODULE_DIR.$module_name.'.class.php';


$method_name = $arr_url['method'];


 


if (file_exists($module_file)) {


include $module_file;




$obj_module = new $module_name();




if (!method_exists($obj_module, $method_name)) {


    die("要调用的方法不存在");


} else {


    if (is_callable(array($obj_module, $method_name))) {


   $obj_module -> $method_name($module_name, $arr_url['parms']);


   


   $obj_module -> printResult();


}


}




} else {


die("定义的模块不存在");


}


 


 


?>


 


</body>


</html>

[/code]
[/code]

 

获取请求的uri,然后拿到要加载的模块名、调用方法名,对uri参数进行简单的判断..

 

第三步,模块的编写

根据上述的uri,我们要调用的是Hello模块下的router方法,那么可以在class目录下定义一个名为Hello.class.php的文件(注意linux下是区分大小写的)


[code]
[code]<?php


 


class Hello {




private $_name;


private $_varValue;




function __construct() {


    


}




function router() {


    $this->_name = func_get_arg(0);


    $this->_varValue = func_get_arg(1);


} 




function printResult() {


    echo $this->_name;


    echo "<p>";


    echo var_dump($this->_varValue);


    echo "</p>";


}


}


 


?>

[/code]
[/code]

 

同理,我们可以编写Ha模块..

 

这算是实现了很简单的url路由分发功能了…

 

本文参考:

《用原生PHP写一个像CodeIgniter的路由功能》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: