ThinkPHP3.2 加载过程(三)
上次回顾:
- IS_CGI ,IS_WIN,IS_CLI,MAGIC_QUOTES_GPC干嘛用
IS_WIN 看了一下后面的代码 基本上就是为了保证在不同环境下运行时,由于有些操作系统会对文件路径大小写敏感,定义该参数。对路径进行更严格的检查。
MAGIC_QUOTES_GPC :
if(version_compare(PHP_VERSION,'5.4.0','<')) {
ini_set('magic_quotes_runtime',0);
define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()? true : false);
}else{
define('MAGIC_QUOTES_GPC',false);
}
如果PHP版本为小于5.4的时候 则进行把 magic_quotes_runtime 功能进行关闭 。对于大于5.4版本的PHP默认情况下是关闭的。
为什么要关闭呢?个人的理解是,如果该功能打开的话,我们给服务器传值的时候遇到单引号双引号斜杠的时候会在加上一个斜杠,这个会对路由识别的时候照成很大的影响。不利于路由的解析。同时如果你传入的数据要对数据库进行草的时候,如果存在上述字符的时候,会多加上一个斜杠。
IS_CGI和IS_CLI
关于这两个参数,我目前还明白,只知道和php和apache运行的时候有关。
本次目标:
对ThinkPHP\Library\Think\Think.clas.php的start进行说明
// 注册AUTOLOAD方法
spl_autoload_register('Think\Think::autoload');
// 设定错误和异常处理
register_shutdown_function('Think\Think::fatalError');
set_error_handler('Think\Think::appError');
set_exception_handler('Think\Think::appException');
// 初始化文件存储方式
Storage::connect(STORAGE_TYPE);
利用spl_autoload_register 函数进行注册,目的是以后如果实例某个类时,而该类并不已经被加载的文件中时候,调用注册的函数 autoload。所以该在后面所以的代码中,如果该类并没有被加载过时,通过该该方法进行把类实例化。
至于为什么能成功实例化呢?在TP中我们的我的类都有一定的命名规则 例如 $User = new \Home\Model\UserModel();
我们可以发现其中的规则,Home是我们的模块名称。Model为模块下模型的文件夹,UserModel
才是我们真正的需要实例化的模型类,而autoload方法加载的大致流程就是这样(注意我说的是大致,如果你去看autoload代码,其中还是对某系文件进行了特殊的照顾),autoload找到我们的模块文件,并找到我们的模型类文件夹,然后在去找到我们要的模型类。
而后面的三行代码则是对程序中出现了异常进行调用的方法。他可以帮我记录错误日子,帮我们美化错误页面。
最后一行代码则是初始化TP中对文件进行删除,写入、加载等操作的类。
至于为什么一个Storage就能找到文件夹处理的类呢?Storage也是通过autoload函数才能找到该类,而Storage就是我们说的被autoload函数特殊照顾的类。autoload函数收到如果加载Storage时,对去找到Storage存放的文件位置。
$runtimefile = RUNTIME_PATH.APP_MODE.'~runtime.php';
if(!APP_DEBUG && Storage::has($runtimefile)){
Storage::load($runtimefile);
}else{
if(Storage::has($runtimefile))
Storage::unlink($runtimefile); //删除文件
$content = '';
// 读取应用模式 如果aplication\common\conf\core.php 存在 则读取,不存在这读取Thinkphp\Mode\common。php
$mode = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php';
// 加载核心文件 // 加载应用模式配置文件 load_config 会根据文件的后缀名进行调用对于的文件进行加载 并且利用C函数进行配置的设置
// 读取当前应用模式对应的配置文件 判断是否是新浪SEA 如果是新浪的SEA 那么APP_MODE为SEA 否则是common // 加载模式别名定义 // 加载应用别名定义文件 CONF_PATH= appliction\common\conf // 加载模式行为定义 // 加载应用行为定义 // 加载框架底层语言包 THINK_PATH=thinphp C('DEFAULT_LANG')=zh-cn if(!APP_DEBUG){
$content .= "\nnamespace { Think\\Think::addMap(".var_export(self::$_map,true).");";
$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(Hook::get(),true).');}';
Storage::put($runtimefile,strip_whitespace('<?php '.$content));
}else{
// 调试模式加载系统默认的配置文件
C(include THINK_PATH.'Conf/debug.php');
// 读取应用调试配置文件
if(is_file(CONF_PATH.'debug'.CONF_EXT))
C(include CONF_PATH.'debug'.CONF_EXT);
}
}
接下来运行的代码(把其中的一些部分进行删除),第一行
$runtimefile = RUNTIME_PATH.APP_MODE.'~runtime.php';
定义编译文件的路径,应该程序比较死嘛,所以如果存在编译过的文件,那么他的路径也是一定的。那么这个文件有什么用呢?集体的说就是else下面的把很多配置文件include进来都保存到该文下,可能也有一些后面的文件中的代码。基本就是我把正常运行情况下那些不变的代码保存到该文件中,那么我下次直接加载这个文件,我就不需要一次次的去反复IO操作读取那么文件,提高框架的效率。
而else中的代码则是把个各种配置文件加载到框架中(注意是配置文件,例如别名配置文件,他会按照数组的形式报错其中,key是别名,value则是路径)
// 加载应用模式配置文件 load_config 会根据文件的后缀名进行调用对于的文件进行加载 并且利用C函数进行配置的设置
foreach ($mode['config'] as $key=>$file){
is_numeric($key)?C(load_config($file)):C($key,load_config($file));
}
该行对对C函数进行初始化赋值,利用Thinkphp\Mode\common.php下的config数组中的目录进行加载配置。从此C函数就有很很多的配置文件信息了。我就可以通过C函数进行查询。同样别和模型行为也是相同的原理
// 加载应用行为定义
if(is_file(CONF_PATH.'tags.php'))
// 允许应用增加开发模式配置定义
Hook::import(include CONF_PATH.'tags.php');
如用户存在aplication\common\conf\tags.php的行为定义,那么加载他到全局的行为定义模版中。那样用户的行为定义就可以在全局调用。
// 加载框架底层语言包 THINK_PATH=thinphp C('DEFAULT_LANG')=zh-cn
L(include THINK_PATH.'Lang/'.strtolower(C('DEFAULT_LANG')).'.php');
定义语音包(说来惭愧,应为重来没有用过,所以也没如何去了解,这里就不说太多),配置文件中DEFAULT_LANG定义是zh-cn
if(!APP_DEBUG){
$content .= "\nnamespace { Think\\Think::addMap(".var_export(self::$_map,true).");";
$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(Hook::get(),true).');}';
Storage::put($runtimefile,strip_whitespace('<?php '.$content));
}else{
// 调试模式加载系统默认的配置文件
C(include THINK_PATH.'Conf/debug.php');
// 读取应用调试配置文件
if(is_file(CONF_PATH.'debug'.CONF_EXT))
C(include CONF_PATH.'debug'.CONF_EXT);
}
如果不再debug模式下面,那么会把上面的配置文件信息数组取下来,报错到编译的文件下面,如果在debug模式下面,那么会去加载debug配置文件信息到C函数下,方便我们进行调试。
// 读取当前应用状态对应的配置文件 如果配置了状态文件,那么加载到其中
if(APP_STATUS && is_file(CONF_PATH.APP_STATUS.CONF_EXT))
C(include CONF_PATH.APP_STATUS.CONF_EXT); // 设置系统时区
date_default_timezone_set(C('DEFAULT_TIMEZONE')); // 检查应用目录结构 如果不存在则自动创建 如果信息观察刚下载下来的目录时候,我们会发现 Application里面是没有多余的文件夹的,这这个时候,
该方法就实现了创建出默认的分组
if(C('CHECK_APP_DIR')) {
$module = defined('BIND_MODULE') ? BIND_MODULE : C('DEFAULT_MODULE');
if(!is_dir(APP_PATH.$module) || !is_dir(LOG_PATH)){
// 检测应用目录结构
Build::checkDir($module);
}
} // 记录加载文件时间
G('loadTime');
// 运行应用
App::run(); //app作为核心类 在52行被加载进入 后面将会开始路由,模版加载等一些了操作
总结:
这主要还是对配置文件进行各种初始化,特别是C函数,应该这个函数我们后面会经常碰到。
这里我们发现TP给我们提供了对C函数进行个性化配置的设置,
一个是如果存在aplication\common\conf\core.php 那么它将优于Thinkphp\Mode\common.php被加载
如果我们定义了状态文件配置,那么它会去加载状态文件配置信息
ThinkPHP3.2 加载过程(三)的更多相关文章
- ThinkPHP3.2 加载过程(四)
前言: 由于比较懒散,但是又是有点强迫症,所以还是想继续把ThinkPHP3.2的加载过程这个烂尾楼补充完整. ========================================分割线= ...
- ThinkPHP3.2 加载过程(一)
加载过程(官方介绍) : 用户URL请求 调用应用入口文件(通常是网站的index.php) 载入框架入口文件(ThinkPHP.php) 记录初始运行时间和内存开销 系统常量判断及定义 载入框架引导 ...
- ThinkPHP3.2 加载过程(二)
回顾: 上次介绍了 ThinkPHP 的 Index.PHP入口文件.但只是TP的入口前面的入口(刷boss总是要过好几关才能让你看到 ,不然boss都没面子啊),从Index.PHP最后一行把我们引 ...
- spring容器启动的加载过程(三)
第十步: public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { /** * Load bean def ...
- AngularJS进阶(三十九)基于项目实战解析ng启动加载过程
基于项目实战解析ng启动加载过程 前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理.回过头来总结一下angular的启动过程. 下面以实际项目为例进行简要讲解. 1.载入ng库 2 ...
- Tomcat8源码笔记(三)Catalina加载过程
之前介绍过 Catalina加载过程是Bootstrap的load调用的 Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...
- 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线
重温.NET下Assembly的加载过程 最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后 ...
- Tomcat源码分析三:Tomcat启动加载过程(一)的源码解析
Tomcat启动加载过程(一)的源码解析 今天,我将分享用源码的方式讲解Tomcat启动的加载过程,关于Tomcat的架构请参阅<Tomcat源码分析二:先看看Tomcat的整体架构>一文 ...
- 工厂模式模拟Spring的bean加载过程
一.前言 在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...
随机推荐
- window 便笺
windows的便签很方便人们记录日常工作安排,但是不是所有人都知道如何调用,下面介绍下如何调用windows便签: 1.win + R --> StikyNot 2.弹出便签界面 3.右击底 ...
- 英语阅读积累<一>
Passage 1.Woodpecker 惹treat or trick There are many apple trees in a garden. They’re good friend ...
- 【Android 应用开发】Activity 状态保存 OnSaveInstanceState參数解析
作者 : 韩曙亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38297083 一. 相关方法简单介绍 1. 状态保存方法演示 ...
- Nginx+Keepalived+Tomcat之动静分离的web集群
#vi /etc/nginx/nginx.conf############################################user nginx nginx;worker_process ...
- form表单普通提交预览显示,读取显示tmp文件
<html> <head> <meta http-equiv="content-type" content="text/html; char ...
- android119 侧滑菜单
MainActivity.java package com.heima52.slidemenu; import com.heima52.slidemenu.view.SlideMenu; import ...
- C#_约束 实现可排序单链表
using System; using System.Collections.Generic; using System.Linq; using System.Text; /* 使用 约束 实现可排序 ...
- Asp.Net 5使用第三方容器
这几天在学习Asp.Net 5,现在文档以及博客之类的资料实在太少了,不看源码几乎举步维艰,好在全都是开源的,看看微软的代码也获益良多. 看到DependencyInjection的代码里除了默认的容 ...
- Tomcat启动报错org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-apr-8080"]”
1.使用netstat查看端口8080的使用情况: netstat -ano | findstr 8080 结果为: 最后一列表示使用8080端口的进程PID,如果返回结果为空则说明没有被使用. 2. ...
- 使用SDWebImage 怎么获取指定请求对应的缓存图片呢?
SDWebImage会对我们加载的网络数据进行缓存,但有时候我们想要拿到缓存数据中的图片,可以通过下个方法实现: UIImage *thumbnailImage = [[SDImageCache sh ...