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]的更多相关文章

  1. 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 ...

  2. vue 中router.go;router.push和router.replace的区别

    vue 中router.go:router.push和router.replace的区别:https://blog.csdn.net/div_ma/article/details/79467165 t ...

  3. vue中router.go、router.push和router.replace的区别

    router.go(n) 这个方法的参数是一个整数,意思是在history记录中向前或者后退多少,类似window.history.go(n) router.push(location) 想要导航到不 ...

  4. vue 中router.go、router.push和router.replace的区别

    router.go(n) 这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n) router.push(location) 想要 ...

  5. 【react router路由】<Router> <Siwtch> <Route>标签

    博客 https://www.jianshu.com/p/ed5e56994f13?from=timeline 文档 http://react-guide.github.io/react-router ...

  6. [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 ...

  7. $router.query和$router.params的区别

    类型于get(query) 和 post(params) 1.query方式传参和接收参数   传参: this.$router.push({ path:"/xxx" query: ...

  8. 【Vue】【Router】手动跳转用 this.$router.push() 时 $router 未定义的问题

    初入Vue,手写路由跳转时的问题: toXxxRoute: () => { this.$router.push({'path': '/xxx', 'name': 'xxx'}) } 由于使用了箭 ...

  9. .6-浅析express源码之Router模块(2)-router.use

    这一节继续深入Router模块,首先从最常用的use开始. router.use 方法源码如下: proto.use = function use(fn) { var offset = 0; var ...

随机推荐

  1. CodeForces 450B 矩阵

    A - Jzzhu and Sequences Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  2. 数据库开发基础-SQl Server 存储过程

    存储过程: 存储过程(stored procedure)有时也称为sproc.存储过程存储于数据库中而不是在单独的文件中,有输入参数.输出参数以及返回值等. 在数据库中,创建存储过程和创建其他对象的过 ...

  3. MVC3中使用RadioButtonFor()

    创建页面  进行初始化   默认 男 被选中 <div class="label"> <div class="editor-label"> ...

  4. tableView使用的易忘技术点(相对于自己)

    1.在tableView设置右向导航指示箭头 cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator; 2.tableView的系 ...

  5. 启动Hadoop HA Hbase zookeeper spark

    服务器角色 服务器 192.168.58.180 192.168.58.181 192.168.58.182 192.168.58.183 Name CentOSMaster Slvae1 Slave ...

  6. HTTP Status 500 - Servlet.init() for servlet springmvc threw exception

    自己的当前环境是ubuntu14.04 64位,tomtcat7和tomcat8,eclipse luna,然后跑了一直spring的demo项目爆了上述的错误,由于这个项目用的是spring3.2在 ...

  7. git命令的使用 【备用】

    *下面为对本地仓库进行操作 [将文件提交到本地仓库] git add 文件名                     将文件添加到暂存区 git status                      ...

  8. editGrid分录表格

    waf("分录id").wafGrid("setCellEditorAllConfig", "字段名", "filteritem& ...

  9. editGrid自定义列自定义F7

    添加自定义列,配置控制自定义F7 自定义F7的地址为连接界面的url /dynamicPage.do?event=initialize&method=doEvent&uipk=com. ...

  10. pycharm和输入法的冲突bug

    Solution:Either upgrade IBus to version 1.5.11 or add "export IBUS_ENABLE_SYNC_MODE=1" to ...