使用Composer从零开发一个简单的web框架(03)-路由

获取和解析参数

编辑core/functions.php,添加相关功能函数

<?php
namespace core;


/**
 * 确认目录存在
 * @param string $path
 */
function path_sure($path) {
    if (!file_exists($path)) mkdir($path, 0777, true);
}

/**
 * 获取原始 uri
 * @param string $uri
 * @return string
 * @example /admin/Index/Index.html?a=111&b=222 => /admin/Index/Index.html
 */
function url_original($uri) {
    $t = explode('?', $uri, 2);

    return $t[0];
}

/**
 * 通过 uri 得到 mod
 * @param string $uri
 * @param string $root
 * @return array
 * @example /admin/Index/Index.html => [admin, Index, Index]
 */
function url_to_mod($uri, $root = '/') {
    $uri     = explode($root, $uri, 2);
    $uri     = explode('.', urldecode($uri[1]), 2);
    $uri    = explode('/', $uri[0]);

    $mod    = [];
    foreach ($uri as $v) $v !== '' && $mod[] = $v;

    return $mod;
}

/**
 * 获取完整 uri
 * @return string
 * @example http://xxx.com|https://xxx.com|http://xxx.com:88|https://xxx.com:88
 */
function uri_full() {
    $pageURL = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
    $pageURL .= $_SERVER['HTTP_HOST'];

    return $pageURL;
}

编辑core/App.php,添加parsestart函数

// 解析参数
private function parse($argv) {
    // cli 命令行模式(php public/index.php app/controller/method)
    if ('cli' === PHP_SAPI) {
        $mod = url_to_mod('/' . $argv[1]);
    } else {
        $uri = url_original($_SERVER['REQUEST_URI']);
        $mod = url_to_mod($uri);
    }

    return $mod;
}

// 拼接控制器和函数并运行
function start($mod) {
    // 检查是否设置了默认 应用、控制器、方法
    defined('DEFAULT_APP') or define('DEFAULT_APP', 'home');
    defined('DEFAULT_CONTROLLER') or define('DEFAULT_CONTROLLER', 'Index');
    defined('DEFAULT_METHOD') or define('DEFAULT_METHOD', 'index');

    if (empty($mod) || !is_array($mod)) {
        // cli 命令行模式
        if ('cli' === PHP_SAPI) {
            echo 'run as: php public/index.php app/controller/method';
        } else {
            header('Location:' . uri_full() . '/' . DEFAULT_APP . '/' . DEFAULT_CONTROLLER . '/' . DEFAULT_METHOD);
        }
        exit();
    }

    $method = null;
    if ($mod[1]) {
        $app        = $mod[0];
        $controller = $mod[1];
        $filename   = PATH_APP . $app . '/controller/' . $controller . '.php';
        if (file_exists($filename)) {
            if ($mod[2]) $method = $mod[2];
        } else {
            $controller = DEFAULT_CONTROLLER;
            $method     = $mod[1];
        }
    } else {
        $app        = $mod[0];
        $controller = DEFAULT_CONTROLLER;
        $method     = DEFAULT_METHOD;
    }

    define('APP',       $app);
    define('CONTROLLER',$controller);

    // 控制器类文件名大写
    $controllerFile = ucfirst($controller);
    $module = "app\\{$app}\\controller\\{$controllerFile}";
    echo '$module:' . $module . ',method:' . $method;
}

编辑 core/App.php 文件,修改构造函数相关调用

public function __construct($argv) {
    $this->setEnv();
    $mod = $this->parse($argv);
    $this->start($mod);
}

测试

新建app/home/controller/Hello.php文件

浏览器访问 phpweb.com/home/hello/world 或控制台运行 php public/index.php home/hello/world,输出

$module:app\home\controller\Hello,method:world

浏览器访问 phpweb.com/home/hello 或控制台运行 php public/index.php home/hello,输出

$module:app\home\controller\Hello,method:

这时我们发现 method 是没有的,这种情况下个章节处理

浏览器访问 phpweb.com/home 或控制台运行 php public/index.php home,输出

$module:app\home\controller\Index,method:index

浏览器访问 http://phpweb.com,输出

$module:app\home\controller\Index,method:Index

因为框架解析参数时,发现为空,跳转到了默认 应用/控制器/方法

制台运行 php public/index.php,输出

run as: php public/index.php app/controller/method

输出直接显示怎么使用命令行的提示

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 6

$_SERVER['REQUEST_URI'] 这个值不存在,环境是 phpEnv

4个月前 评论
mirahs (楼主) 4个月前
mirahs (楼主) 4个月前
wfdaj (作者) 4个月前
mirahs (楼主) 4个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!