美文网首页
ThinkPHP 源码分析(二):运行应用

ThinkPHP 源码分析(二):运行应用

作者: 小拿大魔王 | 来源:发表于2016-12-07 22:44 被阅读0次

tp 框架在加载完各种文件,做好准备之后,才开始要肩负起运行应用的重任。在 Think\Think::start() 方法的最后,App::run() 方法登场。

    /**
     * 应用程序初始化
     * @access public
     * @return void
     */
    static public function init() {
        // 加载动态应用公共文件和配置
        load_ext_file(COMMON_PATH);

        // 日志目录转换为绝对路径 默认情况下存储到公共模块下面
        C('LOG_PATH',   realpath(LOG_PATH).'/Common/');

        // 定义当前请求的系统常量
        define('NOW_TIME',      $_SERVER['REQUEST_TIME']);
        define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']);
        define('IS_GET',        REQUEST_METHOD =='GET' ? true : false);
        define('IS_POST',       REQUEST_METHOD =='POST' ? true : false);
        define('IS_PUT',        REQUEST_METHOD =='PUT' ? true : false);
        define('IS_DELETE',     REQUEST_METHOD =='DELETE' ? true : false);

        // URL调度
        Dispatcher::dispatch();

        if(C('REQUEST_VARS_FILTER')){
            // 全局安全过滤
            // 对数组中的每个成员递归地应用用户函数
            array_walk_recursive($_GET,     'think_filter');
            array_walk_recursive($_POST,    'think_filter');
            array_walk_recursive($_REQUEST, 'think_filter');
        }

        // URL调度结束标签
        Hook::listen('url_dispatch');         

        define('IS_AJAX',       ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false);

        // TMPL_EXCEPTION_FILE 改为绝对地址
        C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE')));
        return ;
    }

App::run() 中最重要的是两句代码,这两句分别执行了该类中的 init 和 exec 方法。在这两个方法执行的前后,还有三个钩子被监听,这三个钩子分别 app_init、app_begin、app_end。

init 方法是 App 类中的应用程序初始化方法,它将完成 Think\Think::start() 未完成的部分初始化工作。剩下的初始化工作的重点是解析请求的 URL,在解析 URL 时,先是定义当前请求的系统常量,然后调用了 Dispatcher::dispatch() 方法,Dispatcher 类是 tp 框架中负责完成 URL 解析、路由和调度的类,这里调用的 dispatch 方法的作用是将 URL映射到控制器,也就是从 URL 中解析出对应的模型、控制器和操作。这样 tp 框架就知道它该调用哪个模型,哪个控制器,以及哪个操作了。

    /**
     * 应用程序初始化
     * @access public
     * @return void
     */
    static public function init() {
        // 加载动态应用公共文件和配置
        load_ext_file(COMMON_PATH);

        // 日志目录转换为绝对路径 默认情况下存储到公共模块下面
        C('LOG_PATH',   realpath(LOG_PATH).'/Common/');

        // 定义当前请求的系统常量
        define('NOW_TIME',      $_SERVER['REQUEST_TIME']);
        define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']);
        define('IS_GET',        REQUEST_METHOD =='GET' ? true : false);
        define('IS_POST',       REQUEST_METHOD =='POST' ? true : false);
        define('IS_PUT',        REQUEST_METHOD =='PUT' ? true : false);
        define('IS_DELETE',     REQUEST_METHOD =='DELETE' ? true : false);

        // URL调度
        Dispatcher::dispatch();

        if(C('REQUEST_VARS_FILTER')){
               // 全局安全过滤
            // 对数组中的每个成员递归地应用用户函数
               array_walk_recursive($_GET,          'think_filter');
               array_walk_recursive($_POST,     'think_filter');
               array_walk_recursive($_REQUEST,     'think_filter');
          }

        // URL调度结束标签
        Hook::listen('url_dispatch');         

        define('IS_AJAX',       ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false);

        // TMPL_EXCEPTION_FILE 改为绝对地址
        C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE')));
        return ;
    }

init 方法运行完后,exec 方法开始负责执行应用程序。首先它会创建控制器实例,并获得当前操作名。之后调用 invokeAction 方法,此方法将执行控制器实例中相应的操作。

        try{
            self::invokeAction($module,$action);
        } catch (\ReflectionException $e) {
            // 方法调用发生异常后 引导到__call方法处理
            $method = new \ReflectionMethod($module,'__call');
            $method->invokeArgs($module,array($action,''));
        }

在 invokeAction 方法中,使用到了 PHP 的两个反射类,ReflectionClass 和 ReflectionMethod。这两个类可以让我们动态的得到类和方法的信息,以及动态调用对象的方法。借助于这两个类,我们可以检测,即将执行的控制器实例中的操作,其访问控制是否为 public,以及是否是类方法。

至此,一次完整的 tp 框架执行流程走到了终点。

相关文章

网友评论

      本文标题:ThinkPHP 源码分析(二):运行应用

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