[PHP] 实现路由映射到指定控制器
自定义路由的功能,指定到pathinfo的url上,再次升级之前的脚本
SimpleLoader.php
<?php
class SimpleLoader{
public static function run($rules=array()){
header("content-type:text/html;charset=utf-8");
self::register();
self::commandLine();
self::router($rules);
self::pathInfo();
}
//自动加载
public static function loadClass($class){
$class=str_replace('\\', '/', $class);
$dir=str_replace('\\', '/', __DIR__);
$class=$dir."/".$class.".php";
if(!file_exists($class)){
header("HTTP/1.1 404 Not Found");
}
require_once $class;
}
//命令行模式
public static function commandLine(){
if(php_sapi_name()=="cli"){
$_SERVER['PATH_INFO']="";
foreach ($_SERVER['argv'] as $k=>$v) {
if($k==0) continue;
$_SERVER['PATH_INFO'].="/".$v;
}
}
}
//路由模式
public static function router($rules){
if(isset($_SERVER['PATH_INFO']) && !empty($rules)){
$pathInfo=ltrim($_SERVER['PATH_INFO'],"/");
foreach ($rules as $k=>$v) {
$reg="/".$k."/i";
if(preg_match($reg,$pathInfo)){
$res=preg_replace($reg,$v,$pathInfo);
$_SERVER['PATH_INFO']='/'.$res;
}
}
}
}
//pathinfo处理
public static function pathInfo(){
if(isset($_SERVER['PATH_INFO'])){
$pathinfo=array_filter(explode("/", $_SERVER['PATH_INFO']));
for($i=1;$i<=count($pathinfo);$i++){
$key=isset($pathinfo[$i]) ? $pathinfo[$i] : '';
$value=isset($pathinfo[$i+1]) ? $pathinfo[$i+1] :"";
switch ($i) {
case 1:
$_GET['m']=ucfirst($key);
break;
case 2:
$_GET['c']=ucfirst($key);
break;
case 3:
$_GET['a']=$key;
break;
default:
if($i>3){
if($i%2==0){
$_GET[$key]=$value;
}
}
break;
}
}
}
$_GET['m']=!empty($_GET['m']) ? ucfirst($_GET['m']) : 'Index';
$_GET['c']=!empty($_GET['c']) ? ucfirst($_GET['c']) : 'Index';
$_GET['a']=!empty($_GET['a']) ? $_GET['a'] : 'index';
$class="\\Controller\\{$_GET['m']}\\{$_GET['c']}";
$controller=new $class;
if(method_exists($controller, $_GET['a'])){
$controller=new $class;
$controller->$_GET['a']();
}else{
header("HTTP/1.1 404 Not Found");
echo "404";
}
}
//致命错误回调
public static function shutdownCallback(){
$e=error_get_last();
if(!$e) return;
self::myErrorHandler($e['type'],'<font color="red">Fatal Error</font> '.$e['message'],$e['file'],$e['line']);
}
//错误处理
protected static function myErrorHandler($errno,$errstr,$errfile,$errline){
list($micseconds,$seconds)=explode(" ",microtime());
$micseconds=round($micseconds*1000);
$micseconds=strlen($micseconds)==1 ? '0'.$micseconds : $micseconds;
if(php_sapi_name()=="cli"){
$break="\r\n";
}else{
$break="<br/>";
}
$mes="[".date("Y-m-d H:i:s",$seconds).":{$micseconds}] ".$errfile." ".$errline." line ".$errstr.$break;
echo $mes;
}
//注册
public static function register(){
error_reporting(0);
set_error_handler(function($errno,$errstr,$errfile,$errline){
self::myErrorHandler($errno,$errstr,$errfile,$errline);
});
register_shutdown_function(function(){
self::shutdownCallback();
});
spl_autoload_register("self::loadClass");
}
}
如何使用
index.php
<?php
//路由映射
$rules=array(
'^user$'=>'User/User/getUserList',
'^user\/(\d+)$'=>'User/User/getUserById/id/$1',
'^user\/(\d+)\/article$'=>'User/User/getUserArticle/uid/$1'
);
require_once "SimpleLoader.php";
SimpleLoader::run($rules);
控制器啥样
\Controller\User\User.php
<?php
namespace Controller\User; class User{
public function getUserById(){
echo "用户信息id {$_GET['id']} 的信息";
}
public function getUserList(){
echo "用户列表";
}
public function getUserArticle(){
echo "用户id {$_GET['uid']} 的文章列表";
}
}
效果呢:



[PHP] 实现路由映射到指定控制器的更多相关文章
- 第三百零四节,Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器
Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器 这一节主讲url控制器 一.urls.py模块 这个模块是配置路由映射的模块,当用户访问一个 ...
- 二 Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器
Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器 这一节主讲url控制器 一.urls.py模块 这个模块是配置路由映射的模块,当用户访问一个 ...
- [Buffalo]ASP.NET MVC路由映射
Asp.Net的路由系统旨在通过注册URl模版与物理文件之间的映射进而实现请求地址与文件路径之间的分离,但对于Asp.Net Mvc应用来说,请求的目标却是定义在某个Controller类型中的Act ...
- ASP.NET的路由系统:路由映射
总的来说,我们可以通过RouteTable的静态属性Routes得到一个基于应用的全局路由表,通过上面的介绍我们知道这是一个类型的RouteCollection的集合对象,我们可以通过调用它的MapP ...
- Django-url路由映射与views逻辑处理
一.URL路由映射 路由映射模块,主要完成url与views视图函数的映射.当一个url请求到来时,会按照这个模块中的url地址从上到下进行匹配,如果匹配成功,将执行映射试图中的函数:反之将返回404 ...
- 第二百六十八节,Tornado框架-路由映射之二级域名支持,html模板继承以及导入
Tornado框架-路由映射之二级域名支持,html模板继承以及导入 二级域名路由映射add_handlers()设置二级域名路由映射 注意:二级域名需要结合服务器ip绑定域名 框架引擎 #!/usr ...
- 第二百六十四节,Tornado框架-基于正则的动态路由映射分页数据获取计算
Tornado框架-基于正则的动态路由映射分页数据获取计算 分页基本显示数据 第一步.设置正则路由映射配置,(r"/index/(?P<page>\d*)", inde ...
- 第二百五十七节,Tornado框架-路由映射,逻辑处理,文件归类配置
Tornado框架-路由映射,逻辑处理,文件归类配置 Tornado框架 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起 ...
- Asp.net MVC 基于Area的路由映射
对于一个较大规模的Web应用,我们可以从功能上通过Area将其划分为较小的单元.每个Area相当于一个独立的子系统,具有一套包含Models.Views和Controller在内的目录结构和配置文件. ...
随机推荐
- Ajax学习笔记(二)
二.prototype库具体解释 1.prototype库的使用 //导入下载好的prototype.js文件 <script type="text/javascript" ...
- android 内置视频目录
在做引导界面的时候有一个视频文件, 把它放在res/raw目录下面. 引用方法 如下: videoView = (VideoView) findViewById(R.id.video_view); v ...
- android自定义view仿照MIUI中音量控制效果
先看效果图: 这就是miui中的音量效果图,实现思路是自定义视图,绘制圆环,然后设置进度显示. 核心代码在onDraw中实现如下: @Override protected void onDraw(Ca ...
- node.js中log4js的使用
以前用过forever进程守护的日志记录到指定文件,但是只能保存到一个文件中不能分片,这样到只日志文件越来越大, forever start -s -l ./forever.log app.js -l ...
- eclipse从数据库逆向生成Hibernate实体类
做项目必然要先进行数据库表设计,然后根据数据库设计建立实体类(VO),这是理所当然的,但是到公司里做项目后,让我认识到,没有说既进行完数据库设计后还要再“自己”建立一变VO.意思是,在项目设计时,要么 ...
- 解析表达式到lucene.net的Query
查询的时候有自己的查询格式,为了统一并且方便的搜索lucene.net 于是就写了个解析格式,大体上覆盖了几乎所有的lucene.net的query了.当然少了公共扩展库里包含的regexQuery, ...
- Rails4 中 因为secret key 引起在production环境下无法运行
错误信息 Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` ...
- winform 指定浏览器打开链接
Process myProcess = new Process(); myProcess.StartInfo.FileName = "firefox.exe";//&quo ...
- SQL语句中将Datetime类型转换为字符串类型
0 Feb 22 2006 4:26PM CONVERT(CHAR(19), CURRENT_TIMESTAMP, 0) 1 02/22/06 CONVERT(CHAR(8), CURRENT_ ...
- 转:探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
前言 相信这样一个问题,大家都不会陌生, “有什么的方法可以使Android的程序APK不用安装,而能够直接启动”. 发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实 ...