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)
如果我们访问一下不存在的游戏应用,例如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]<?phpclass 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的路由功能》
相关文章推荐
- PHP实现一个简单url路由功能
- PHP实现一个简单url路由功能实例
- PHP实现一个简单url路由功能
- PHP简单实现MVC框架路由功能模式
- 一个php简单的框架实现,仅实现了简单路由层
- 基于PHP实现一个简单的在线聊天功能
- PHP简单实现MVC框架路由功能模式
- 用HTML+PHP写一个留言板来进行XSS测试&学习 第三篇(简单的过滤标签功能实现&绕过)
- php实现简单路由router功能
- 一个简单实现了PHP图片上传功能
- PHP实现的简单路由和类自动加载功能
- js实现一个简单的锁屏功能
- 一个简单的php实现的MySQL数据浏览器
- node简单实现一个更改头像功能
- PHP实现的简单sha1加密功能示例
- php实现简单的验证码功能
- PHP 结合MYSQL简单的实现了Todo List 功能
- 一个简单的PHP验证码实现代码
- PHP实现简单的验证码功能机制
- 【转】PHP实现MVC开发: 一个简单的MVC