专栏首页陶士涵的菜地[PHP] 实现路由映射到指定控制器

[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']} 的文章列表";
    }
}

效果呢:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [PHP] 命令行执行整合pathinfo模拟定时任务

    现在执行其他方法是同步的,可以再优化成开新线程执行这些方法,就不会阻塞主线程的定时了

    陶士涵
  • [PHP] 自定义错误处理

    陶士涵
  • [PHP] 单例模式-创建型设计模式

    类型前面的问号表示参数或返回值可为空(null),是PHP7的新特性例如,?string str 表示str的值可以为null或字符串此用法不只局限于静态类型,...

    陶士涵
  • 调度服务 ScheduledExecutorService 经常卡顿问题的排查及解决方法

    如上述代码所示,启动 10 个调度线程,延迟 10 秒,开始执行定时逻辑,然后每隔 2 秒执行一次定时任务。定时任务类为TaskWorker,其要做的事就是根据...

    CG国斌
  • 《JavaScript 模式》读书笔记(4)— 函数3

    函数可以动态定义,也可以分配给变量。如果创建了一个新函数,并且将其分配给保存了另外函数的同一个变量,那么就以一个新函数覆盖了旧函数。在某种程度上,回收了旧函数...

    zaking
  • 掘安CTF刷题

    然后在network里抓到了getScore.php?reset getScore.php的页面,

    ly0n
  • lombok插件

    IDE: IntelliJ IDEA  首先在设置的插件栏中安装lombok,然后使用如下的pom依赖: <dependency>    <groupId>or...

    用户1134788
  • 强烈推荐:一个简单高效的截图工具

    工欲善其事必先利其器,今天我给大家推荐一个非常简单,非常高效,非常好用的截图工具。没办法,我这个人就是看见好东西喜欢和大家一起分享。真心是忍不住要分享一下。 1...

    非著名程序员
  • Excel大批量数据的导入和导出,如何做优化?

    Java对Excel的操作一般都是用POI,但是数据量大的话可能会导致频繁的FGC或OOM,这篇文章跟大家说下如果避免踩POI的坑,以及分别对于xls和xlsx...

    趣学程序-shaofeer
  • set\list\map部分源码解析

    List、Set实现Collection接口。Map并没有实现任何接口,但内部聚合了一个Collection对象

    洋仔聊编程

扫码关注云+社区

领取腾讯云代金券