轻量级router[类似laravel router]
github地址:https://github.com/NoahBuscher/Macaw/blob/master/Macaw.php
代码加上一些注释,方便以后再看。
<?php namespace NoahBuscher\Macaw; /**
* method static Macaw get(string $route, Callable $callback)
* method static Macaw post(string $route, Callable $callback)
* method static Macaw put(string $route, Callable $callback)
* method static Macaw delete(string $route, Callable $callback)
* method static Macaw options(string $route, Callable $callback)
* method static Macaw head(string $route, Callable $callback)
*/
class Macaw {
public static $halts = false;
public static $routes = array();
public static $methods = array();
public static $callbacks = array();
public static $patterns = array(
':any' => '[^/]+',
':num' => '[0-9]+',
':all' => '.*',
);
public static $error_callback;
/**
* Defines a route w/ callback and method
* 注册路由,把注册的方法(GET,POST..),uri,closure分别push到对应的数组中
*/
public static function __callstatic( $method, $params ) {
$uri = $params[0];
$callback = $params[1];
array_push( self::$routes, $uri );
array_push( self::$methods, strtoupper( $method ) );
array_push( self::$callbacks, $callback );
}
/**
* Defines callback if route is not found
* 可以自定义没找到路由时执行的方法
*/
public static function error( $callback ) {
self::$error_callback = $callback;
} /**
* 自定义是否匹配到一次就停止,true停止,false不停止即可以定义多个同名路由,通过foreach全部执行
* @param boolean $flag true / false
* @return none
*/
public static function haltOnMatch( $flag = true ) {
self::$halts = $flag;
}
/**
* Runs the callback for the given request
* 根据当前的uri匹配对应的路由并执行
*/
public static function dispatch() {
$uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ); //路径部分(包括前边的/),不包括参数
$method = $_SERVER['REQUEST_METHOD']; //方法 GET / POST / PUT / DELETE
$searchs = array_keys( static::$patterns );
$replaces = array_values( static::$patterns );
$found_route = false; //check if route is defined without regex,检查是否定义了路由(非:any,:all形式的)
if ( in_array( $uri, self::$routes ) ) {
$route_pos = array_keys( self::$routes, $uri ); //返回匹配路由的键值,可能多个(同名路由)
foreach ( $route_pos as $route ) {
if ( self::$methods[$route] == $method ) { //寻找路由对应的方法名(GET,POST...),确定是否注册。
$found_route = true;
//if route is not an object,检测对应闭包函数是function还是controller route
if ( !is_object( self::$callbacks[$route] ) ) {
//grab all parts based on a / separator 控制器路由
$parts = explode( '/', self::$callbacks[$route] );
//collect the last index of the array
$last = end( $parts );
//grab the controller name and method call
$segments = explode( '@', $last );
//instanitate controller
$controller = new $segments[0]();
//call method
$controller->$segments[1]();
if ( self::$halts )return; //匹配一次就停止? }else {
//call closure
call_user_func( self::$callbacks[$route] );
if ( self::$halts )return;
} } }
}else {
//check if defined with regex 是否注册了正则路由(:any,:num..)
$pos = 0;
foreach ( self::$routes as $route ) {
if ( strpos( $route, ':' ) !== false ) {
$route = str_replace( $searchs, $replaces, $route );
}
if ( preg_match( '#^'.$route.'$#', $uri, $matched ) ) {
if ( self::$methods[$pos] == $method ) {
$found_route = true;
array_shift( $matched );
if ( !is_object( self::$callbacks[$pos] ) ) {
//grab all parts based on a / separator
$parts = explode( '/', self::$callbacks[$pos] );
//collect the last index of the array
$last = end( $parts );
//grab the controller name and method call
$segments = explode( '@', $last );
//instanitate controller
$controller = new $segments[0]();
//call method and pass any extra parameters to the method
$controller->$segments[1]( implode( ",", $matched ) );
if ( self::$halts ) {
return;
}else {
call_user_func_array( self::$callbacks[$pos], $matched );
if ( self::$halts ) return;
} }
}
}
$pos++;
}
} //return the error callback if the route was not found
if ( $found_route == false ) {
if ( !self::$error_callback ) {
self::$error_callback = function() {
header( $_SERVER['SERVER_PROTOCOL']." 404 Not Found" ); //请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
echo '404';
}
}
call_user_func( self::$error_callback ); }
}
}
轻量级router[类似laravel router]的更多相关文章
- vue router.push(),router.replace(),router.go()和router.replace后需要返回两次的问题
转载:https://www.cnblogs.com/lwwen/p/7245083.html https://blog.csdn.net/qq_15385627/article/details/83 ...
- vue 中router.go;router.push和router.replace的区别
vue 中router.go:router.push和router.replace的区别:https://blog.csdn.net/div_ma/article/details/79467165 t ...
- vue中router.go、router.push和router.replace的区别
router.go(n) 这个方法的参数是一个整数,意思是在history记录中向前或者后退多少,类似window.history.go(n) router.push(location) 想要导航到不 ...
- vue 中router.go、router.push和router.replace的区别
router.go(n) 这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n) router.push(location) 想要 ...
- 【react router路由】<Router> <Siwtch> <Route>标签
博客 https://www.jianshu.com/p/ed5e56994f13?from=timeline 文档 http://react-guide.github.io/react-router ...
- [Angular 2] Router basic and Router Params
When we define router in Angualr 2, we use @RouteConcfig() When we want to display component, we use ...
- $router.query和$router.params的区别
类型于get(query) 和 post(params) 1.query方式传参和接收参数 传参: this.$router.push({ path:"/xxx" query: ...
- 【Vue】【Router】手动跳转用 this.$router.push() 时 $router 未定义的问题
初入Vue,手写路由跳转时的问题: toXxxRoute: () => { this.$router.push({'path': '/xxx', 'name': 'xxx'}) } 由于使用了箭 ...
- .6-浅析express源码之Router模块(2)-router.use
这一节继续深入Router模块,首先从最常用的use开始. router.use 方法源码如下: proto.use = function use(fn) { var offset = 0; var ...
随机推荐
- 【BZOJ 4456】【UOJ #184】【ZJOI 2016】旅行者
http://www.lydsy.com/JudgeOnline/problem.php?id=4456 http://uoj.ac/problem/184 参考(抄)的晨爷的题解(代码) 对矩形进行 ...
- 【BZOJ 1503】【NOI 2004】郁闷的出纳员
$Splay$模板题. 复习一下伸展树的模板. 一定不要忘了push啊!!! 对于减工资后删掉员工的操作,我选择插入一个$min+delta_{减少的工资}$的节点,把它$Splay$到根,砍掉它自己 ...
- DOS常用命令收集(长期更新)
命令列表 命令 说明 ASSOC 显示或修改文件扩展名关联. ATTRIB 显示或更改文件属性. BREAK 设置或清除扩展式 CTRL+C 检查. BCDEDIT 设置启动数据库中的属性以控制启动加 ...
- Sigmaplot激活码获取地址
SigmaPlot是一款高质量绘图软件,可以帮助用户以超简单表格形式来更清楚有效地展现工作结果,有了SigmaPlot你可以不用在电脑前久坐就可以制作出高质量的图形. 软件完美兼容Microsoft ...
- Mysql 5.7.12解压版的安装及配置系统编码
这篇博文是由于上篇EF+MySql博文引发的,上篇博文中在Seed方法中插入中文数据到Mysql数据库中乱码,后来网上找了N种方法也没解决.重装了MySql并在安装过程中配置了系统编码,此篇记录一下. ...
- Lyaer 单弹出层获取数据
案例完整代码如下 var cls = layer.open({ title: "请选择被换班人", type: 2, ...
- iOS支付宝的使用
打开“APViewController.m”文件,对以下三个参数进行编辑. 二.集成支付宝到自己的工程 1.启动Xcode,为了方便快速开发,将解压包里面的AlipaySDK.bundle和Alipa ...
- iOS推送后页面跳转
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...
- js 对象 copy 对象
function clone(myObj) { if (typeof (myObj) != 'object') return myObj; if (myObj == null) return myOb ...
- oninput等表单事件
oninput等表单事件 过去我们常使用keydown和keyup辅助表单元素的处理,这要求处理时,表单元素必须处于激活(聚焦)状态.oninput事件可以实时监听文本框的输入变化. 现代浏览器支 ...