首页 > 代码库 > Thinkphp3.2新手篇之系统运行流程1
Thinkphp3.2新手篇之系统运行流程1
如果公司使用的tp框架,那么作为新人在首先会被要求了解tp的系统运行流程,本文章意在帮助新童鞋快速了解tp系统流程。流程说明按照tp手册给出的进行(序号也相同,方便大家查看):
1.用户URL请求,2.调用应用入口文件(这里以index.php为例)
大部分网站是利用url重写隐藏了index.php的,这里的方法请查看tp手册。首先执行index.php,
1 // 应用入口文件 2 3 // 检测PHP环境 4 if(version_compare(PHP_VERSION,‘5.3.0‘,‘<‘)) die(‘require PHP > 5.3.0 !‘); 5 6 // 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false 7 define(‘APP_DEBUG‘,True); 8 9 // 定义应用目录 10 define(‘APP_PATH‘,‘./Application/‘); 11 12 // 引入ThinkPHP入口文件 13 require ‘./ThinkPHP/ThinkPHP.php‘;
首先判断php版本是否为5.3.0以上,然后开启调试模式(后面的流程会说明),在定义路径时tp默认的是相对路径,但是使用绝对路径会加快运行速度。tp手册上使用的方法是:
realpath()方法获取绝对路径,这里推荐一个方法getcwd();最后进入核心包中的Thinkphp.php;注意:整个网站流程的执行地址都是在网站根目录的index.php上,不要因为流程进入了其他控制器和方法就认为执行地址也随之变化了,这是新手学习流程的一个误区。
3.载入框架入口文件(Thinkphp.php) 4.记录初始运行时间和内存开销 5.系统常量判断及定义
Thinkphp.php进入之后会定义很多常量如果常量已经在index.php中定义了,则不能重新定义。值得注意的是下面的代码:
1 if(!defined(‘__ROOT__‘)) { 2 $_root = rtrim(dirname(_PHP_FILE_),‘/‘); 3 define(‘__ROOT__‘, (($_root==‘/‘ || $_root==‘\\‘)?‘‘:$_root)); 4 }
这里拿出来是因为当我们使用网站根目录绝对地址时,若我们是本地文件,故根目录形式为‘/xxx‘,但是在项目上线之后的地址为‘/‘,那么问题就出现了,‘/xxx‘后面接地址是要先写一个‘/‘的,而‘/‘后面如果再写一个‘/‘就重复了,为了避免上线和本地之间的路径冲突,这里做了替换,当$_root为‘/‘时,直接替换为空,这样就可以和本地一样直接接‘/‘了。
1 // 加载核心Think类 2 require CORE_PATH.‘Think‘.EXT; 3 // 应用初始化 4 Think\Think::start();
接下来执行TP3.2\ThinkPHP\Library\Think下的Think.class.php中的start方法。
6.载入框架引导类(Think\Think)并执行Think::start方法进行应用初始化,----(7-23)同
首先,注册AUTOLOAD方法,设定错误和异常处理,初始化文件存储方式(这部分暂时不用详细了解)。然后就是重点,预编译文件:
1 //[额外注释]定义预编译文件名称(以应用模式开头,默认为common) 2 $runtimefile = RUNTIME_PATH.APP_MODE.‘~runtime.php‘; 3 if(!APP_DEBUG && Storage::has($runtimefile)){ 4 //[额外注释]若调试模式关闭,并且预编译文件存在,则加载 5 Storage::load($runtimefile); 6 }else{ 7 //[额外注释]若调试模式打开,并且预编译文件存在,则删除; 8 if(Storage::has($runtimefile)) 9 Storage::unlink($runtimefile); 10 //[额外注释]初始化预编译参数$content 11 $content = ‘‘; 12 // 读取应用模式 13 //[额外注释]第一步---读取应用配置文件,默认为ThinkPHP/Mode/common.php 14 $mode = include is_file(CONF_PATH.‘core.php‘)?CONF_PATH.‘core.php‘:MODE_PATH.APP_MODE.‘.php‘; 15 // 加载核心文件 16 //[额外注释]---common.php为二维数组,开始遍历(函数和类文件) 17 foreach ($mode[‘core‘] as $file){ 18 if(is_file($file)) { 19 //[额外注释]加载函数和类文件 20 include $file; 21 //[额外注释]---获取文件内容,并保存到$content中 22 if(!APP_DEBUG) $content .= compile($file); 23 } 24 } 25 26 // 加载应用模式配置文件 27 //[额外注释]load_config判断不同类型的配置文件,并返回其内容 28 //[额外注释]配置文件首次加载,惯例配置文件convention.php和应用配置文件config.php 29 //[额外注释]若$file为关联数组则用使用原键值 30 //[额外注释]调用C函数,传入数组为初始化,故$_CONFIG更新 31 //[额外注释]读取预编译文件会跳过此步骤,故部署模式下修改这2个配置文件无法生效 32 foreach ($mode[‘config‘] as $key=>$file){ 33 is_numeric($key)?C(load_config($file)):C($key,load_config($file)); 34 } 35 36 // 读取当前应用模式对应的配置文件 37 //[额外注释]配置文件读取应用配置,非common应用模式有效,读取config_xxx.php 38 if(‘common‘ != APP_MODE && is_file(CONF_PATH.‘config_‘.APP_MODE.CONF_EXT)) 39 C(load_config(CONF_PATH.‘config_‘.APP_MODE.CONF_EXT)); 40 41 // 加载模式别名定义 42 //[额外注释]官方别名定义加载,映射数组更新至$_map 43 //[额外注释]addMap()更新类中$_map的值,是数组直接更新,不是数组则创建为数组,并且更新$_map 44 if(isset($mode[‘alias‘])){ 45 self::addMap(is_array($mode[‘alias‘])?$mode[‘alias‘]:include $mode[‘alias‘]); 46 } 47 48 // 加载应用别名定义文件 49 //[额外注释]自定义别名定义加载,映射数组更新至$_map 50 if(is_file(CONF_PATH.‘alias.php‘)) 51 self::addMap(include CONF_PATH.‘alias.php‘); 52 53 // 加载模式行为定义 54 //[额外注释]官方默认行为标签绑定数组加载 55 //[额外注释]只传1参数为合并导入,2参数为覆盖导入(手册有说明) 56 //[额外注释]hook类中的$_tags已经更新 57 if(isset($mode[‘tags‘])) { 58 Hook::import(is_array($mode[‘tags‘])?$mode[‘tags‘]:include $mode[‘tags‘]); 59 } 60 61 // 加载应用行为定义 62 //[额外注释]自定义行为标签绑定数组加载 63 //[额外注释]hook类中的$_tags已经更新 64 if(is_file(CONF_PATH.‘tags.php‘)) 65 // 允许应用增加开发模式配置定义 66 Hook::import(include CONF_PATH.‘tags.php‘); 67 68 // 加载框架底层语言包 69 //[额外注释]L方法加载框架语言包$_lang已经更新 70 L(include THINK_PATH.‘Lang/‘.strtolower(C(‘DEFAULT_LANG‘)).‘.php‘); 71 72 //[额外注释]基础加载完毕,开始生成预编译文件 73 if(!APP_DEBUG){ 74 //[额外注释]若调试模式关闭 75 //[额外注释]预编译文件中,整合一遍配置参数 76 $content .= "\nnamespace { Think\\Think::addMap(".var_export(self::$_map,true).");"; 77 //[额外注释]预编译文件中,整合一遍语言参数,配置参数,行为绑定参数 78 $content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).‘);Think\Hook::import(‘.var_export(Hook::get(),true).‘);}‘; 79 //[额外注释]将内容导入预编译文件 80 Storage::put($runtimefile,strip_whitespace(‘<?php ‘.$content)); 81 }else{ 82 // 调试模式加载系统默认的配置文件 83 //[额外注释]若调试模式开启,则需要加载额外的配置文件debug.php 84 C(include THINK_PATH.‘Conf/debug.php‘); 85 // 读取应用调试配置文件 86 //[额外注释]若debug.php存在,则读取 87 if(is_file(CONF_PATH.‘debug‘.CONF_EXT)) 88 C(include CONF_PATH.‘debug‘.CONF_EXT); 89 } 90 }
代码比较长,额外注释已整合进入代码中。首先作判断,若调试模式关闭(调试模式开启则不生成预编译文件)并且文件存在,则直接加载该文件,后面的判断不执行。
总结:预编译文件中含有的内容为:1.common.php中的core,2.部分配置文件,3.映射,4.行为,5.语言
未完待续......
Thinkphp3.2新手篇之系统运行流程1