PS:如果是从我前面一篇文章过来的小伙伴,请忽略,如果是新来的小伙伴,如果你对app执行之前系统做了啥不太了解,可以参考我的另一篇文章:
https://blog.csdn.net/weixin_44187959/article/details/93589445
下面我们开始来说thinkphp3.2的app.php 到底做了啥
//----------------------------
//我们先看看程序的流程
//大概的流程就如下图所示,我们现在开始讲每一个块,做了啥
//----------------------------
static public function run() {
//执行初始化钩子
Hook::listen('app_init');
App::init();
// 执行app开始阶段的钩子函数
Hook::listen('app_begin');
// Session初始化
if(!IS_CLI){
session(C('SESSION_OPTIONS'));
}
// 记录应用初始化时间
G('initTime');
App::exec();
// 执行应用结束的钩子
Hook::listen('app_end');
return ;
}
//----------------------
//首先我们有必要先聊一聊Hook
//-----------------------
//这个是hook的执行数组
static private $tags = array();
//--------------------------------------
//这个方法是向$tags中添加钩子,具体执行逻辑为:
//如果参数1不为空,参数2为数组则将参数1添加至执行数组,数组添加到参数1为k值的二维数组
//如果参数1不为空,参数2不是数组,则将参数2保存至参数1为k值的数组中去
//---------------------------------------
static public function add($tag,$name) {
if(!isset(self::$tags[$tag])){
self::$tags[$tag] = array();
}
if(is_array($name)){
self::$tags[$tag] = array_merge(self::$tags[$tag],$name);
}else{
self::$tags[$tag][] = $name;
}
}
//-----------------------------
//这里主要是将钩子加载到执行数组中去
//-----------------------------
static public function import($data,$recursive=true)
{
if(!$recursive)
{
// 覆盖导入
self::$tags = array_merge(self::$tags,$data);
}
else
{
// 合并导入
foreach ($data as $tag=>$val)
{
if(!isset(self::$tags[$tag]))
self::$tags[$tag] = array();
if(!empty($val['_overlay']))
{
// 可以针对某个标签指定覆盖模式
unset($val['_overlay']);
self::$tags[$tag] = $val;
}
else
{
// 合并模式
self::$tags[$tag] = array_merge(self::$tags[$tag],$val);
}
}
}
}
//------------------------
//Hook的核心,插件的执行函数
//该函数执行系统与定义函数并记录
//------------------------
static public function listen($tag, &$params=NULL) {
if(isset(self::$tags[$tag])) {
if(APP_DEBUG) {
G($tag.'Start');
trace('[ '.$tag.' ] --START--','','INFO');
}
dump(self::$tags);
dump(self::$tags[$tag]);
foreach (self::$tags[$tag] as $name) {
APP_DEBUG && G($name.'_start');
$result = self::exec($name, $tag,$params);
if(APP_DEBUG){
G($name.'_end');
trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO');
}
if(false === $result) {
// 如果返回false 则中断插件执行
return ;
}
}
if(APP_DEBUG) { // 记录行为的执行日志
trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');
}
}
return;
}
//----------------------------
//由于系统并未定义Hook::listen('app_init')对应的插件,所以我们从app::init()开始
//分析App::init();
//-----------------------------
// 加载动态应用公共文件和配置
load_ext_file(COMMON_PATH);
// URL调度
//------该函数请参照我的博客贴出地址,这里不多赘述
// http
Dispatcher::dispatch();
// 定义当前请求的系统常量
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);
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);
// URL调度结束标签
// 这里主要是判断是否为debug模式,记录运行状态
Hook::listen('url_dispatch');
// 日志目录转换为绝对路径
// 定义两个常量,并且返回
C('LOG_PATH',realpath(LOG_PATH).'/');
// TMPL_EXCEPTION_FILE 改为绝对地址
C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE')));
return ;