上次回顾:

  • 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 加载过程(三)的更多相关文章

  1. ThinkPHP3.2 加载过程(四)

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

  2. ThinkPHP3.2 加载过程(一)

    加载过程(官方介绍) : 用户URL请求 调用应用入口文件(通常是网站的index.php) 载入框架入口文件(ThinkPHP.php) 记录初始运行时间和内存开销 系统常量判断及定义 载入框架引导 ...

  3. ThinkPHP3.2 加载过程(二)

    回顾: 上次介绍了 ThinkPHP 的 Index.PHP入口文件.但只是TP的入口前面的入口(刷boss总是要过好几关才能让你看到 ,不然boss都没面子啊),从Index.PHP最后一行把我们引 ...

  4. spring容器启动的加载过程(三)

    第十步: public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { /** * Load bean def ...

  5. AngularJS进阶(三十九)基于项目实战解析ng启动加载过程

    基于项目实战解析ng启动加载过程 前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理.回过头来总结一下angular的启动过程. 下面以实际项目为例进行简要讲解. 1.载入ng库 2 ...

  6. Tomcat8源码笔记(三)Catalina加载过程

    之前介绍过 Catalina加载过程是Bootstrap的load调用的  Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...

  7. 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

    重温.NET下Assembly的加载过程   最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后 ...

  8. Tomcat源码分析三:Tomcat启动加载过程(一)的源码解析

    Tomcat启动加载过程(一)的源码解析 今天,我将分享用源码的方式讲解Tomcat启动的加载过程,关于Tomcat的架构请参阅<Tomcat源码分析二:先看看Tomcat的整体架构>一文 ...

  9. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

随机推荐

  1. oracle查找重复记录

    SELECT *FROM t_info aWHERE ((SELECT COUNT(*)          FROM t_info          WHERE Title = a.Title) &g ...

  2. JNI/NDK开发指南(四)——字符串处理

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/42066665 从第三章中能够看出JNI中的基本类型和Java中的基本类型都是一一相应的,接 ...

  3. linux 内核之旅

    http://www.kerneltravel.net/?p=534 http://mp.weixin.qq.com/mp/homepage?__biz=MzI3NzA5MzUxNA==&hi ...

  4. 文件和目录之link、unlink、remove和rename函数

    任何一个文件可以有多个目录项指向其i节点.创建一个指向现有文件的链接的方法是使用link函数. #include <unistd.h> int link( const char *exis ...

  5. Android Service 服务(一)—— Service .

    http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一(Activit ...

  6. c++20道面试题

    摘自传智播客论坛 问1:请用简单的语言告诉我C++ 是什么?答:C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛.C++支持多种编程范式 --面向对象编程.泛型编程和过程化编程. 其编程领 ...

  7. Android之利用HTTP网络通信实现与PHP的交互(三)

    Android与PHP的交互是通过Http网络编程来实现的,利用php访问数据库,并且操作数据库中的数据,利用php作为接口,使Android连接数据库. 一般情况下,我们使用Json格式进行传输,利 ...

  8. 自定义手势_GestureOverlayVIew

    xml文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns ...

  9. 2014年6月5日 深圳 IBM 安全解决方案会议通知

    2014年6月5日 深圳 IBM 安全解决方案会议通知 http://gdtesting.com/news.php?id=191 时间: 2014年6月5日 地点: 深圳大中华喜来登 议程: IBM安 ...

  10. mongodb使用mongoose分组查询

    一个分组查询的例子: model.aggregate([{$match: ops}, {$unwind: '$details'}, {$sort: {create_at: -1}}, { $group ...