美文网首页
单一入口,根据uri解析路由

单一入口,根据uri解析路由

作者: 云龙789 | 来源:发表于2019-04-17 15:24 被阅读0次

    在做单一入口的时候,根据URI 对应的参数设置路由和控制器

    • 思路 xx.com/index/index?name=test&age=22

    将斜杠后面的第一个参数赋值为控制器,第二个参数赋值为控制器中的方法,
    ?后面的参数不需要处理,直接 _GET 即可获取到 如果没有传递方法参数,则使用默认的参数,要注意控制器或者方法的参数里面有没有问号,即_GET 参数,比如 xx.com/index?name=test&age=22,要做好处理,遇到问号,就直接返回即可

    <?php
    
    namespace Core\Lib;
    
    /**
     * 路由类
     * Class Route
     * @package Core\Lib
     */
    class Route
    {
        /**
         * @var string  控制器名   默认是 indexController
         */
        public $controller = 'indexController';
    
        /**
         * @var string  方法名  默认是 index
         */
        public $action = 'index';
    
        /**
         *  xx.com/index/index
         *  支持两种传参方式  如果传参,则必须写全控制器与方法
         * Route constructor.
         */
        public function __construct()
        {
            // $_SERVER['REQUEST_URI'] 这个值其实是一定会出现的,如果 url 只有站点,则显示 '/',代表访问首页
            if (in_array($_SERVER['REQUEST_URI'], ['/', '/index.php'])) {
                return true;
            }
            //  如果不在 ['/', '/index.php'],则代表肯定有值
            $arr = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
            // /  后的第一个参数是控制器名
            if (isset($arr[0])) {
                if (mb_strpos($arr[0], '?') !== false) {
                    list($controller, $request_get) = explode('?', $arr[0]);
                    $this->controller = $controller. 'Controller';
                    // 如果有问号,则表示使用的默认控制器和方法
                    return true;
                }
                $this->controller = $arr[0] . 'Controller';
            }
            unset($arr[0]);
            // 第二个参数是控制器方法
            if (isset($arr[1])) {
                if (mb_strpos($arr[1], '?') !== false) {
                    list($method, $request_get) = explode('?', $arr[1]);
                    $this->action = $method;
                    //  表示有问号传值
                    return true;
                } else {
                    $this->action = $arr[1];
                }
            }
            // 第三个参数是 回调对应的 Service ,是哦自己项目中使用到的一个参数值
            if (isset($arr[2])) {
                if (mb_strpos($arr[2], '?') !== false) {
                    //  表示有问号传值
                    list($service, $request_get) = explode('?', $arr[2]);
                    $_ENV['service'] = $service;
                } else {
                    $_ENV['service'] = $arr[2];
                }
            }
    
    // 以下方式是设置成 /key/value 的这种形式的。
    //        if (!$_GET) {
    //            //  如果使用 ?  方式传递参数,则不再处理
    //            unset($arr[1]);
    //            // url 多余部分转换成 get 参数  index/index/id/1
    //            // 重新获取控制器和方法以外的参数,奇数是值,奇数加1是键,
    //            $i = 2;
    //            while (isset($arr[$i])) {
    //                if (!isset($arr[$i + 1])) {
    //                    //  不存在这个键,则肯定到此为止了
    //                    $get_values[$arr[$i]] = '';
    //                    break;
    //                }
    //                $_GET[$arr[$i]] = $arr[$i + 1];
    //                $i = $i + 2;
    //            }
    //        }
    
        }
    
    }
    

    应用

         // 获取路由
            $route = new Route();
            // 2.判断控制器是否存在
            $class = '/App/Controller/' . $route->controller;
            if (!is_file(BASE_PATH . $class . '.php')) {
                self::responseError('路由不存在', -401);
            }
    
            $class = str_replace('/', '\\', $class);
            $controller = new  $class();
            //  3.判断控制器中的方法是否存在
            $action = $route->action;
            if (!method_exists($controller, $action)) {
                self::responseError('路由不存在', -402);
            }
    
            // 4. 请求控制器中的方法
            $response = call_user_func([$controller, $route->action]);
            // 正常返回肯定是数组形式,不会执行到这一步
            if (!is_array($response)) {
                self::responseError('返回数据格式有误,请联系客服,谢谢!', -501);
            }
            //  如果 返回的是 responseError  status !==200 则表示返回有误,记录错误日志   回调中有可能没有 status 状态
            $response['status'] = isset($response['status']) ? $response['status'] : -10001;
            if ($response['status'] !== 200) {
                app_log($response, Log::LOG_RESPONSE_ERROR);
            }
    
            echo json_encode($response, JSON_UNESCAPED_UNICODE);
            die;
    

    使用 composer 实现自动加载即可,不需要自己再使用 spl_autoload_register()函数
    composer.json

    {
      "autoload": {
        "psr-4": {
          "App\\": "app/",
          "Core\\": "core/"
        },
        "files": [
          "core/common/function.php"
        ]
      }
    }
    

    执行 composer autoload

    相关文章

      网友评论

          本文标题:单一入口,根据uri解析路由

          本文链接:https://www.haomeiwen.com/subject/zvdnwqtx.html