Thinkphp源码分析系列(一)–入口文件

正如官方文档上所介绍的,thinkphp使用单一入口,所有的请求都从默认的index.php文件进入。当然不是说一定非得从index.php进入,这应该取决于你的服务器配置,一般服务器都会有默认的首页,比如index.php,index.html,所以一般访问域名都会先默认访问上述文件,你还可以创建多个应用,一个应用对应一个入口文件,所有的入口文件都引用一套thinkphp类库。

我们来看index.php都干了些什么.  index.php主要任务是定义应用名称和引用类库路径。当然也可以定义一些其他的系统常量。

// 检测PHP环境
if(version_compare(PHP_VERSION,‘5.3.0‘,‘<‘)) die(‘require PHP > 5.3.0 !‘);

// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
define(‘APP_DEBUG‘,True);

// 定义应用目录
define(‘APP_PATH‘,‘./test/‘);

// 引入ThinkPHP入口文件
require ‘./ThinkPHP/ThinkPHP.php‘;

thinkphp官方建议在实际部署应用的时候,我们建议除了应用入口文件和Public资源目录外,其他文件都放到非WEB目录下面,具有更好的安全性。

接下来就应该是ThinkPHP.php文件,这个文件主要是用于框架环境的一些设置,包括常用路径,版本检测,系统信息等。

<?php

// 记录开始运行时间
$GLOBALS[‘_beginTime‘] = microtime(TRUE);
// 记录内存初始使用
define(‘MEMORY_LIMIT_ON‘,function_exists(‘memory_get_usage‘));
if(MEMORY_LIMIT_ON) $GLOBALS[‘_startUseMems‘] = memory_get_usage();

// 版本信息
const THINK_VERSION = ‘3.2.2‘;

// URL 模式定义
const URL_COMMON = 0; //普通模式
const URL_PATHINFO = 1; //PATHINFO模式
const URL_REWRITE = 2; //REWRITE模式
const URL_COMPAT = 3; // 兼容模式

// 类文件后缀
const EXT = ‘.class.php‘;

// 系统常量定义
//定义当前入口文件所在的目录,即thinkphp框架的目录
defined(‘THINK_PATH‘) or define(‘THINK_PATH‘, __DIR__.‘/‘);
//定义网站应用所在的目录。一般来说,在index.php文件中我们会定义一下应用路径,如果说我们在index.php文件中没有定义APP_PATH,那么这里就会执行define(‘APP_PATH‘, dirname($_SERVER[‘SCRIPT_FILENAME‘]).‘/‘);这里会获取当前执行脚本的服务器端的绝对路径。一般是index.php文件所在的目录。在我的电脑上即D:/phpStudy/WWW/thinkphp/,即网站的根目录。
defined(‘APP_PATH‘) or define(‘APP_PATH‘, dirname($_SERVER[‘SCRIPT_FILENAME‘]).‘/‘);
defined(‘APP_STATUS‘) or define(‘APP_STATUS‘, ‘‘); // 应用状态 加载对应的配置文件
defined(‘APP_DEBUG‘) or define(‘APP_DEBUG‘, false); // 是否调试模式

/*
这里定义应用模式。到底什么是应用模式?
thinkphp框架为开发者提供了更改核心框架的机会。我们知道一个php框架的核心是定义一些重要的配置文件,引入一些重要的类库和函数以及适应当前主机环境的的php配置等。所以我们可以把这些核心中需要引入的文件代码分离出来,全部定义在一个php配置文件中,这个php配置文件就叫做模式的配置文件。然后我们根据模式不同去引用对应的配置文件,分析配置文件中的配置项,并运行之,从而达到改变框架核心的目的。
就拿最为常用的普通模式来说明。
我们在入口文件中定义了app_mode为common,然后在执行thinkphp的start方法的时候就会去分析定义的模式名称并且根据模式名称去mode文件夹下去寻找模式对应的common.php文件,
 // 读取应用模式
 $mode = include is_file(CONF_PATH.‘core.php‘)?CONF_PATH.‘core.php‘:MODE_PATH.APP_MODE.‘.php‘;
在此文件中定义了用于扩展核心的配置项,在引入了这个文件后,我们可以查看start方法后续就会一一去引入配置项中所定义的各个文件。
与此同时,tp默认支持SAE环境,也就是说官方已经给我们写好了SAE环境的核心框架扩展的代码,只带适当的时候触发。
*/
if(function_exists(‘saeAutoLoader‘)){// 自动识别SAE环境
defined(‘APP_MODE‘) or define(‘APP_MODE‘, ‘sae‘);
defined(‘STORAGE_TYPE‘) or define(‘STORAGE_TYPE‘, ‘Sae‘);
}else{
defined(‘APP_MODE‘) or define(‘APP_MODE‘, ‘common‘); // 应用模式 默认为普通模式
defined(‘STORAGE_TYPE‘) or define(‘STORAGE_TYPE‘, ‘File‘); // 存储类型 默认为File
}

defined(‘RUNTIME_PATH‘) or define(‘RUNTIME_PATH‘, APP_PATH.‘Runtime/‘); // 系统运行时目录
defined(‘LIB_PATH‘) or define(‘LIB_PATH‘, realpath(THINK_PATH.‘Library‘).‘/‘); // 系统核心类库目录
defined(‘CORE_PATH‘) or define(‘CORE_PATH‘, LIB_PATH.‘Think/‘); // Think类库目录
defined(‘BEHAVIOR_PATH‘)or define(‘BEHAVIOR_PATH‘, LIB_PATH.‘Behavior/‘); // 行为类库目录
defined(‘MODE_PATH‘) or define(‘MODE_PATH‘, THINK_PATH.‘Mode/‘); // 系统应用模式目录
defined(‘VENDOR_PATH‘) or define(‘VENDOR_PATH‘, LIB_PATH.‘Vendor/‘); // 第三方类库目录
defined(‘COMMON_PATH‘) or define(‘COMMON_PATH‘, APP_PATH.‘Common/‘); // 应用公共目录
defined(‘CONF_PATH‘) or define(‘CONF_PATH‘, COMMON_PATH.‘Conf/‘); // 应用配置目录
defined(‘LANG_PATH‘) or define(‘LANG_PATH‘, COMMON_PATH.‘Lang/‘); // 应用语言目录
defined(‘HTML_PATH‘) or define(‘HTML_PATH‘, APP_PATH.‘Html/‘); // 应用静态目录
defined(‘LOG_PATH‘) or define(‘LOG_PATH‘, RUNTIME_PATH.‘Logs/‘); // 应用日志目录
defined(‘TEMP_PATH‘) or define(‘TEMP_PATH‘, RUNTIME_PATH.‘Temp/‘); // 应用缓存目录
defined(‘DATA_PATH‘) or define(‘DATA_PATH‘, RUNTIME_PATH.‘Data/‘); // 应用数据目录
defined(‘CACHE_PATH‘) or define(‘CACHE_PATH‘, RUNTIME_PATH.‘Cache/‘); // 应用模板缓存目录
defined(‘CONF_EXT‘) or define(‘CONF_EXT‘, ‘.php‘); // 配置文件后缀
defined(‘CONF_PARSE‘) or define(‘CONF_PARSE‘, ‘‘); // 配置文件解析方法

// 系统信息
/*
在magic_quotes_gpc=On的情况下,如果输入的数据有
单引号(’)、双引号(”)、反斜线()与 NUL(NULL 字符)等字符都会被加上反斜线。这些转义是必须的,如果这个选项为off,那么我们就必须调用addslashes这个函数来为字符串增加转义。
在php5.4以后就废除了此特性。所以我们在以后就不要依靠这个特性了。为了使自己的程序不管服务器是什么设置都能正常执行。可以在程序开始用get_magic_quotes_runtime检测该设置的状态决定是否要手工处理,或者在开始(或不需要自动转义的时候)用set_magic_quotes_runtime(0)关掉该设置。
判断php版本,小于5.4的就手动关掉,定义常量。大于5.4直接定义常量为false。
*/
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判断解析php服务是由那种服务器软件,是采用那种协议,PHP_ASPI是一个可以直接使用的常量。
如果是nginx+fastcgi环境,那么它的值是cgi-fcgi
如果是apache环境,那么他的值是apache2handler
如果是命令行的形式,那么它的值是cli
PHP_OS PHP所在的操作系统的名字,例如linux和WIN。
充分理解php的各种运行模式,参看:
http://www.jb51.net/article/37756.htm
http://www.cnblogs.com/liuzhang/p/3929198.html
*/
define(‘IS_CGI‘,(0 === strpos(PHP_SAPI,‘cgi‘) || false !== strpos(PHP_SAPI,‘fcgi‘)) ? 1 : 0 );
define(‘IS_WIN‘,strstr(PHP_OS, ‘WIN‘) ? 1 : 0 );
define(‘IS_CLI‘,PHP_SAPI==‘cli‘? 1 : 0);

/*
如果不是命令行模式的话,指定当前运行脚本的文件名。
*/
if(!IS_CLI) {
// 当前文件名
if(!defined(‘_PHP_FILE_‘)) {
if(IS_CGI) {
  //CGI/FASTCGI模式下
  $_temp = explode(‘.php‘,$_SERVER[‘PHP_SELF‘]);
  define(‘_PHP_FILE_‘, rtrim(str_replace($_SERVER[‘HTTP_HOST‘],‘‘,$_temp[0].‘.php‘),‘/‘));
}else {
  define(‘_PHP_FILE_‘, rtrim($_SERVER[‘SCRIPT_NAME‘],‘/‘));
}
}
if(!defined(‘__ROOT__‘)) {
  $_root = rtrim(dirname(_PHP_FILE_),‘/‘);
  define(‘__ROOT__‘, (($_root==‘/‘ || $_root==‘\\‘)?‘‘:$_root));
  }
}

// 加载核心Think类
require CORE_PATH.‘Think‘.EXT;
// 应用初始化
Think\Think::start();
时间: 2024-10-13 17:07:42

Thinkphp源码分析系列(一)–入口文件的相关文章

Cordova Android源码分析系列一(项目总览和CordovaActivity分析)

PhoneGap/Cordova是一个专业的移动应用开发框架,是一个全面的WEB APP开发的框架,提供了以WEB形式来访问终端设备的API的功能.这对于采用WEB APP进行开发者来说是个福音,这可以避免了原生开发的某些功能.Cordova 只是个原生外壳,app的内核是一个完整的webapp,需要调用的原生功能将以原生插件的形式实现,以暴露js接口的方式调用. Cordova Android项目是Cordova Android原生部分的Java代码实现,提供了Android原生代码和上层We

MyBatis 源码分析系列文章合集

1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章中,有4篇文章字数超过了1万,最长的一篇文章约有2.7万字(含代码).考虑到超长文章对读者不太友好,以及拆分文章工作量也不小等问题.遂决定将博文整理成电子书,方便大家阅读. 经过两周紧张的排版,<一本小小的MyBatis源码分析书>诞生了.本书共7章,约300页.本书以电子书的形式发布,大家可自由

SpringMVC源码分析系列

说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时springmvc基于Spring框架,Spring框架想必搞java的同学都很熟悉. 一进Spring的官网就发现了这样一排醒目的文字, spring可以让我们构造简单的.便携的.又快又易于扩展的基于jvm的系统和应用程序. 没错,基于Spring的MVC框架SpringMVC同样也可以构造具有这些特

jQuery源码分析系列(33) : AJAX中的前置过滤器和请求分发器

jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求,分别是: 1.前置过滤器 jQuery. ajaxPrefilter 2.请求分发器 jQuery. ajaxTransport, 3.类型转换器 ajaxConvert 源码结构: jQuery.extend({ /** * 前置过滤器 * @type {[type]} */ ajaxPrefilter: addToPrefiltersOrTransports(prefilters), /** * 请求分发器 *

jQuery源码分析系列(36) : Ajax - 类型转化器

什么是类型转化器? jQuery支持不同格式的数据返回形式,比如dataType为 xml, json,jsonp,script, or html 但是浏览器的XMLHttpRequest对象对数据的响应只有 responseText与responseXML 二种 所以现在我要定义dataType为jsonp,那么所得的最终数据是一个json的键值对,所以jQuery内部就会默认帮你完成这个转化工作 jQuery为了处理这种执行后数据的转化,就引入了类型转化器,如果没有指定类型就依据响应头Con

jQuery源码分析系列(34) : Ajax - 预处理jsonp

上一章大概讲了前置过滤器和请求分发器的作用,这一章主要是具体分析每种对应的处理方式 $.ajax()调用不同类型的响应,被传递到成功处理函数之前,会经过不同种类的预处理(prefilters). 预处理的类型取决于由更加接近默认的Content-Type响应,但可以明确使用dataType选项进行设置.如果提供了dataType选项, 响应的Content-Type头信息将被忽略. 有效的数据类型是text, html, xml, json,jsonp,和 script. dataType:预期

Cordova Android源码分析系列二(CordovaWebView相关类分析)

本篇文章是Cordova Android源码分析系列文章的第二篇,主要分析CordovaWebView和CordovaWebViewClient类,通过分析代码可以知道Web网页加载的过程,错误出来,多线程处理等. CordovaWebView类分析 CordovaWebView类继承了Android WebView类,这是一个很自然的实现,共1000多行代码.包含了PluginManager pluginManager,BroadcastReceiver receiver,CordovaInt

jQuery源码分析系列(38) : 队列操作

Queue队列,如同data数据缓存与Deferred异步模型一样,都是jQuery库的内部实现的基础设施 Queue队列是animate动画依赖的基础设施,整个jQuery中队列仅供给动画使用 Queue队列 队列是一种特殊的线性表,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).队列的特点是先进先出(FIFO-first in first out),即最先插入的元素最先被删除. 为什么要引入队列? 我们知道代码的执行流有异步与同步之分,例如 var a

jquery2源码分析系列目录

学习jquery的源码对于提高前端的能力很有帮助,下面的系列是我在网上看到的对jquery2的源码的分析.等有时间了好好研究下.我们知道jquery2开始就不支持IE6-8了,从jquery2的源码中可以学到很多w3c新的标准( 如html5,css3,ECMAScript).原文地址是:http://www.cnblogs.com/aaronjs/p/3279314.html 关于1.x.x版的jquery源码分析系列,本博客也转载了一个地址http://www.cnblogs.com/jav