ThinkPHP3.2 加载过程(四)

前言:

         由于比较懒散,但是又是有点强迫症,所以还是想继续把ThinkPHP3.2的加载过程这个烂尾楼补充完整。

========================================分割线=================================

 

   上次最后一个篇说道加载APP:run()   ----在ThinkPHP/Library/Think/Thinkclass.php下

在这里说明一下APP在什么时候会被定义并且加载的

         配置文件ThinkPHP/Mode/common.php在ThinkPHP/Library/Think/Thinkclass.php 被引入的时候,APP这个class被同时引入

    // 函数和类文件

    // 函数和类文件
    'core'      =>  array(
        THINK_PATH.'Common/functions.php',
        COMMON_PATH.'Common/function.php',
        CORE_PATH . 'Hook'.EXT,
        CORE_PATH . 'App'.EXT,
        CORE_PATH . 'Dispatcher'.EXT,
        //CORE_PATH . 'Log'.EXT,
        CORE_PATH . 'Route'.EXT,
        CORE_PATH . 'Controller'.EXT,
        CORE_PATH . 'View'.EXT,
        BEHAVIOR_PATH . 'BuildLiteBehavior'.EXT,
        BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT,
        BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT,
    ),

 

因此我们知道APP的class文件地址为ThinkPHP/Library/Think/App.class.php,并且执行下的run方法

    /**
     * 运行应用实例 入口文件使用的快捷方法
     * @access public
     * @return void
     */
    static public function run() {
        // 应用初始化标签
        Hook::listen('app_init');
        App::init();
        // 应用开始标签
        Hook::listen('app_begin');
        // Session初始化
        if(!IS_CLI){
            session(C('SESSION_OPTIONS'));
        }
        // 记录应用初始化时间
        G('initTime');
        App::exec();
        // 应用结束标签
        Hook::listen('app_end');
        return ;
    }

 

对run方法下的代码进行分析

第一段:

        // 应用初始化标签
        Hook::listen('app_init');

 

Hook这THINKPHP叫系统钩子(应该是想钓鱼一样,用这个把鱼勾上来把)

 

引入的时间:应该他是包含在commom.php这个core数组中被引入

 

文件位置:ThinPHP/Library/Think/Hook.class.php

 

第一行:Hook::listen('app_init');

简化代码:

    /**

     * 监听标签的插件

     * @param string $tag 标签名称

     * @param mixed $params 传入参数

     * @return void

     */

    static public function listen($tag, &$params=NULL) {

        if(isset(self::$tags[$tag])) {

            foreach (self::$tags[$tag] as $name) {

                $result =   self::exec($name, $tag,$params);

                if(false === $result) {

                    // 如果返回false 则中断插件执行

                    return ;

                }

            }

        }

        return;

}

 

 

     其中self::exec()代码在下面

 

    /**
     * 执行某个插件
     * @param string $name 插件名称
     * @param string $tag 方法名(标签名)     
     * @param Mixed $params 传入的参数
     * @return void
     */
    static public function exec($name, $tag,&$params=NULL) {
        if('Behavior' == substr($name,-8) ){
            // 行为扩展必须用run入口方法
            $tag    =   'run';
        }
        $addon   = new $name();
        return $addon->$tag($params);
    }

 

 

关于参数app_init在什么时候被传入  定义到了self::$tags()下做简单说明

配置的文件同样是在ThinkPHP/Mode/common.php下的tags数组

通过ThinkPHP/Library/Think/Thinkclass.php

          // 加载模式行为定义
          if(isset($mode['tags'])) {
              Hook::import(is_array($mode['tags'])?$mode['tags']:include $mode['tags']);
          }

 

配置到系统钩子的tags中

 

通过配置文件我们看到app_init对于的类是BuildLiteBehavior 

 

第一段代码总结:

         实例化BuildLiteBehavior类该类地址ThinkPHP/Library/bechavior/BuildLiteBeavior.class.php  并且运行其中的run方法

 

关于BuildLiteBeavior.class.php里面大致的代码 是把之前运行的代码  把之前运行的代码都整理到一起,包括其中的参数的定义等,默认情况下该功能是关闭状态,所以不需要理会

 

第二段

  

 App::init();

 

         集体代码:

    /**
     * 应用程序初始化
     * @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 ;
    }

 

这里大致的内容,通过URL获取其中的模块名:控制器名:方法名

 

第三段:

        // 应用开始标签
        Hook::listen('app_begin');

 

更具之前的经验,app_begin的文件是在ThinkPHP/library/Behavior/ReadHtmlCacheBehavior.php

并且运行这个文件的run方法

   Run方法代码

    // 行为扩展的执行入口必须是run
    public function run(&$params){
        // 开启静态缓存
        if(IS_GET && C('HTML_CACHE_ON'))  {
            $cacheTime = $this->requireHtmlCache();
            if( false !== $cacheTime && $this->checkHTMLCache(HTML_FILE_NAME,$cacheTime)) { //静态页面有效
                // 读取静态页面输出
                echo Storage::read(HTML_FILE_NAME,'html');
                exit();
            }
        }
    }

 

 

如果定义了缓存文件规则  则使用缓存文件,由于默认情况下是关闭

 

第三部分:

        // Session初始化
        if(!IS_CLI){
            session(C('SESSION_OPTIONS'));
        }
        // 记录应用初始化时间
        G('initTime');

 

如果是一个来自网页的请求,则利用配置文件中的SESSION_OPTIONS规则对session进行初始化。

记录初始化时间

 

第四部分:

  App::exec();

 

        具体代码在/ThinkPHP/Library/Think/App.class.php文件下的exec()

    这个方法和基本功能是实现让框架找到对应的控制器和方法。

 

    关于路由和App::exec();方法,下次分开具体说明

总结:

  

    /**
     * 运行应用实例 入口文件使用的快捷方法
     * @access public
     * @return void
     */
    static public function run() {
        // 应用初始化标签
        Hook::listen('app_init'); //默认情况下无效
        App::init();  //通过URL  将模块名  控制器名  和方法名找到
        // 应用开始标签
        Hook::listen('app_begin');  //静态缓存页面 ,默认关闭 
        // Session初始化
        if(!IS_CLI){
            session(C('SESSION_OPTIONS'));  	//根据配置文件中的SESSION_OPTIONS进行session初始化
        }
        // 记录应用初始化时间
        G('initTime');  //做记录
        App::exec();  //知道对于的控制器和方法名  并运行
        // 应用结束标签
        Hook::listen('app_end');//默认关闭  该功能是显示网页请求的一些sql执行,响应时间等参数
        return ;
    }

 

posted on 2015-11-22 01:39  Sunlight1992  阅读(615)  评论(0编辑  收藏  举报

导航