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.语言

未完待续......

时间: 2024-08-05 02:30:17

Thinkphp3.2新手篇之系统运行流程1的相关文章

Struts2系统运行流程(2)

在上一篇中已经说过了Struts2的系统的基本原理(http://blog.csdn.net/xlgen157387/article/details/45840719),下边说一下Struts2的运行流程: 举个简单的案例,就是一个helloworld的案例,下边对其进行进行详细的解释. 案例基础内容: 我们在使用Struts2的时候会在web.xml文件中进行配置过滤器:编写一个Action类,这里起个名字叫做HelloWorldAction:在struts.xml中进行配置这个Action.

[android开发篇]使用系统权限流程

1 声明权限https://developer.android.com/training/permissions/declaring.html 每款 Android 应用都在访问受限的沙盒中运行.如果应用需要使用其沙盒外的资源或信息,则必须请求相应权限.您可以在应用清单中列出相应的权限,声明应用需要此权限. 根据权限的敏感性,系统可能会自动授予权限,或者需要由设备用户对请求进行许可.例如,如果您的应用请求打开设备手电筒的权限,系统将自动授予该权限.但如果您的应用需要读取用户联系人,系统会要求用户

[Spark内核] 第35课:打通 Spark 系统运行内幕机制循环流程

本课主题 打通 Spark 系统运行内幕机制循环流程 引言 通过 DAGScheduelr 面向整个 Job,然后划分成不同的 Stage,Stage 是從后往前划分的,执行的时候是從前往后执行的,每个 Stage 内部有一系列任務,前面有分享過,任务是并行计算啦,这是并行计算的逻辑是完全相同的,只不过是处理的数据不同而已,DAGScheduler 会以 TaskSet 的方式把我们一个 DAG 构造的 Stage 中的所有任务提交给底层的调度器 TaskScheduler,TaskSchedu

操作系统篇-hello world(免系统运行程序)

  一.前言 今天起开始分享关于操作系统的相关知识,本人也是菜鸟一个,正处于学习阶段,这整个操作系统篇也是我边学习边总结的一些结果,希望能给正在学习或者有意向学习操作系统的童鞋带来帮助. 二.有关知识 在进入代码之前,先给大家普及一些硬件知识,如果你已经具备了这方面的知识,可以直接略过这部份. 1.计算机怎么启动操作系统的? 首先,我们思考一个问题,为什么一个硬盘安装系统之后打开计算机电源之后就能正常加载启动呢?这看起来似乎很智能,似乎计算机像活的一样会自动去硬盘中找系统代码并自行加载.其实不然

Spark修炼之道(进阶篇)——Spark入门到精通:第九节 Spark SQL运行流程解析

1.整体运行流程 使用下列代码对SparkSQL流程进行分析,让大家明白LogicalPlan的几种状态,理解SparkSQL整体执行流程 // sc is an existing SparkContext. val sqlContext = new org.apache.spark.sql.SQLContext(sc) // this is used to implicitly convert an RDD to a DataFrame. import sqlContext.implicits

解剖Nginx&#183;模块开发篇(4)模块开发中的命名规则和模块加载与运行流程

1 命名规则 1.1 基本变量 基本变量有三个: ngx_module_t 类型的 ngx_http_foo_bar_module: ngx_command_t 类型的数组 ngx_http_foo_bar_commands: ngx_http_module_t 类型的 ngx_http_foo_bar_module_ctx. 假设你开发了一个 Foo Bar 模块,那么模块名称应该叫: ngx_http_foo_bar_module 命令集合的名字的命名规则: ngx_http_foo_bar

身份认证系统(四)OAuth2运行流程

上一节介绍过什么是OAuth2,这节准备用生动的事例来告诉大家OAuth2运行的流程. 我们来想这样一个场景:假设我们有一个叫做万方网盘的服务是用来帮助用户存储论文文档的,我们向外提供了符合OAuth2标准的APi,可以让第三方程序获取到用户的论文.有一个第三方的程序可以调用我们平台的接口获取用户论文,来帮助用户投稿. 在OAuth中,我们管用户叫做资源拥有者(Resource Owner,RO),投稿应用叫做Client,万方网盘叫做资源服务(Resource Server,RS),昨天我们还

(新手篇)嵌入式Linux C 语言编程环境

嵌入式Linux C 语言编程环境有四部分 1.编译器vi 1.1 vi的基本模式 1.1.1 命令模式(Command Mode) 在该模式下输入命令来控制屏幕光标的移动,字符.单词或行的删除,移动复制段落. 1.1.2 插入模式(Insert Mode) 按[ESC]键可以回到命令行模式.按字母[i]键进入插入模式,就可以写代码了. 1.1.3 低行模式(Last Line Mode) 命令模式下,按[:]键进入低行模式.如“:q”离开 “:w”保存. 2.编译链接器 GCC 2.1 GCC

[Linux学习笔记] Linux系统引导流程(一)

前面我们已经介绍过以CentOS为例的Linux系统的安装以及Linux常用命令的使用,本节内容我们将介绍Linux系统引导流程.当按下电源的那一刻,到我们看到用户界面,这其中都发生了些什么呢?赶快来一探究竟. 下图为Linux系统引导流程过程图: 以下对Linux引导流程过程做一个简单的说明: 1. POST加电自检 POST(POST ON SELF TEST)首先对每一个设备进行检查,完成后会寻找存有引导记录的设备,找到读入操作系统的引导记录,将系统控制权交给引导记录. 2. MBR引导