`
moqiang02
  • 浏览: 556681 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
文章分类
社区版块
存档分类
最新评论

thinkphp执行流程

 
阅读更多
1. 入口文件index.php
用户对url的访问首先被定位到http://<serverIp>/<appName>/index.php, 这里的入口文件index.php做三件事情:1.1, 1.2, 1.3
1.1 定义或载入全局变量
常见的有APP_NAME(项目名称), APP_PATH(项目路径), THINK_PATH(ThinkPHP框架路径);
我研究的是ThinkSNS1.6,它除了用ThinkPHP的全局变量比如THINK_MODE, 又加入了自己定义的一些全局变量,如SITE_PATH, SITE_URL,
注意到ThinkSNS定义了自己的模式ThinkSNS,


define('THINK_MODE','ThinkSNS');


关于ThinkPHP的模式扩展,在ThinkPHP2.0完全开发手册6.10模式扩展章节中有介绍,总的思想是通过模式扩展使得开发者可以定制自己需要使用的ThinkPHP底层框架核心,不必拘泥于ThinkPHP默认的标准模式。

1.2 加载框架入口文件ThinkPHP.php
入口文件通常是ThinkPHP.php,


require(THINK_PATH."/ThinkPHP.php");


而ThinkSNS定义了自己的入口文件ThinkSNS.php,不过总体的思想是一样的。
在这个框架入口文件,做下面的事情:

1.2.1 记录开始运行时间
$GLOBALS['_beginTime'] = microtime(TRUE);


1.2.2 检测THINK_PATH,APP_NAME, APP_PATH
// ThinkPHP系统目录定义
if(!defined('THINK_PATH')) define('THINK_PATH', dirname(__FILE__));
if(!defined('APP_NAME')) define('APP_NAME', basename(dirname($_SERVER['SCRIPT_FILENAME'])));
if(!defined('APP_PATH')) define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']));


1.2.3 检测项目编译缓存目录定义,没有则取项目的Temp目录
1.2.4 加载常量定义文件defines.php和公共函数文件functions.php
require THINK_PATH.'/Common/defines.php';

...

$runtime[] = THINK_PATH.'/Common/functions.php'; // 系统函数


1.2.5 加载核心基类
// 核心基类必须加载
$runtime[] = THINK_PATH.'/Lib/Think/Core/Think.class.php';


1.2.6 加载核心编译文件
核心编译文件列表由文件core.php给出;可以自定制,放在CONFIG_PATH下;或者可以根据扩展模式放在THINK_MODE下;或者使用默认的THINK_PATH.'/Common/core.php'
// 读取核心编译文件列表
if(is_file(CONFIG_PATH.'core.php')) {

// 加载项目自定义的核心编译文件列表
$list = include CONFIG_PATH.'core.php';
}else{
if(defined('THINK_MODE')) {
// 根据设置的运行模式加载不同的核心编译文件
$list = include

THINK_PATH.'/Mode/'.strtolower(THINK_MODE).'.php';
}else{
// 默认核心
$list = include THINK_PATH.'/Common/core.php';
}
}


默认的THINK_PATH.'/Common/core.php'的内容为

// 系统默认的核心列表文件
return array(
THINK_PATH.'/Lib/Think/Exception/ThinkException.class.php', // 异常处理类
THINK_PATH.'/Lib/Think/Core/Log.class.php', // 日志处理类
THINK_PATH.'/Lib/Think/Core/App.class.php', // 应用程序类
THINK_PATH.'/Lib/Think/Core/Action.class.php', // 控制器类
//THINK_PATH.'/Lib/Think/Core/Model.class.php', // 模型类
THINK_PATH.'/Lib/Think/Core/View.class.php', // 视图类
THINK_PATH.'/Common/alias.php', // 加载别名
);


这样就加载了系统核心类库(包括App、Action、Model、View、ThinkException、Log)
1.2.7 生成核心编译缓存~runtime.php
如果没有定义NO_CACHE_RUNTIME, 则把上面步骤中加载的文件统一写到~runtime.php中,下次就可以直接调用核心编译缓存~runtime.php,无需再一一加载


// 生成核心编译缓存 去掉文件空白以减少大小
if(!defined('NO_CACHE_RUNTIME')) {
$compile = defined('RUNTIME_ALLINONE');
$content = compile(THINK_PATH.'/Common/defines.php',$compile);
$content .= compile(defined('PATH_DEFINE_FILE')? PATH_DEFINE_FILE : THINK_PATH.'/Common/paths.php',$compile);
foreach ($runtime as $file){
$content .= compile($file,$compile);
}
if(defined('STRIP_RUNTIME_SPACE') && STRIP_RUNTIME_SPACE == false ) {
file_put_contents(RUNTIME_PATH.'~runtime.php','<?php'.$content);
}else{ file_put_contents(RUNTIME_PATH.'~runtime.php',strip_whitespace('<?php'.$content));
}
unset($content);

}


1.2.8 记录加载文件时间 $GLOBALS['_loadTime']
// 记录加载文件时间
$GLOBALS['_loadTime'] = microtime(TRUE);


1.3 执行应用,实例化App类
//实例化一个网站应用实例
$App = new App();
$App->run();


在调用$App->run()时,具体做的事情,可看ThinkPHP\Lib\Think\Core\App.class.php里的public function run(),

/**
+----------------------------------------------------------
* 运行应用实例 入口文件使用的快捷方法
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
* @return void
+----------------------------------------------------------
*/
public function run() {
$this->init();
// 记录应用初始化时间
if(C('SHOW_RUN_TIME'))
$GLOBALS['_initTime'] = microtime(TRUE);
$this->exec();
$GLOBALS['_endTime'] = microtime(TRUE);
// 保存日志记录
if(C('WEB_LOG_RECORD'))
Log::save();
return ;
}


那么接着看$this->init()做什么事情,根据下面的代码,看到
首先如果编译后的项目文件~app.php存在则直接加载它,如果不存在则调用build函数来生成~app.php;
之后通过define('MODULE_NAME',$this->getModule())和define('ACTION_NAME', $this->getAction())将模块和动作的名字放入全局变量

/**
+----------------------------------------------------------
* 应用程序初始化
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
* @return void
+----------------------------------------------------------
*/
public function init()
{
// 设定错误和异常处理
set_error_handler(array(&$this,"appError"));
set_exception_handler(array(&$this,"appException"));
// 检查项目是否编译过
// 在部署模式下会自动在第一次执行的时候编译项目
if(is_file(RUNTIME_PATH.'~app.php') && (!is_file(CONFIG_PATH.'config.php') || filemtime(RUNTIME_PATH.'~app.php')>filemtime(CONFIG_PATH.'config.php'))) {
// 直接读取编译后的项目文件
C(include RUNTIME_PATH.'~app.php');
}else{
// 预编译项目
$this->build();
}
// 项目开始标签
if(C('TAG_PLUGIN_ON')) tag('app_begin');

// 设置系统时区 PHP5支持
if(function_exists('date_default_timezone_set'))
date_default_timezone_set(C('TIME_ZONE'));

if(C('SESSION_AUTO_START'))
// Session初始化
session_start();

// 应用调度过滤器
// 如果没有加载任何URL调度器
// 默认只支持 QUERY_STRING 方式
// 例如 ?m=user&a=add
if(C('DISPATCH_ON')) {
import('Dispatcher');
Dispatcher::dispatch();
}

if(!defined('PHP_FILE'))
// PHP_FILE 由内置的Dispacher定义
// 如果不使用该插件,需要重新定义
define('PHP_FILE',_PHP_FILE_);

// 取得模块和操作名称
// 可以在Dispatcher中定义获取规则
if(!defined('MODULE_NAME')) define('MODULE_NAME', $this->getModule()); // Module名称
if(!defined('ACTION_NAME')) define('ACTION_NAME', $this->getAction()); // Action操作

// 加载模块配置文件
if(is_file(CONFIG_PATH.strtolower(MODULE_NAME).'_config.php'))
C(include CONFIG_PATH.strtolower(MODULE_NAME).'_config.php');

// 系统检查
$this->checkLanguage(); //语言检查
$this->checkTemplate(); //模板检查

if(C('HTML_CACHE_ON')) { // 开启静态缓存
import('HtmlCache');
HtmlCache::readHTMLCache();
}

// 项目初始化标签
if(C('TAG_PLUGIN_ON')) tag('app_init');

return ;
}


$this->init()执行完后,就完成了定义MODULE_NAME和ACTION_NAME,接着执行
$this->exec(),


/**
+----------------------------------------------------------
* 执行应用程序
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
* @return void
+----------------------------------------------------------
* @throws ThinkExecption
+----------------------------------------------------------
*/
public function exec()
{
// 是否开启标签扩展
$tagOn = C('TAG_PLUGIN_ON');
// 项目运行标签
if($tagOn) tag('app_run');

//创建Action控制器实例
$module = A(MODULE_NAME);
if(!$module) {
// 是否存在扩展模块
$_module = C('_modules_.'.MODULE_NAME);
if($_module) {
// 'module'=>array('classImportPath'[,'className'])
import($_module[0]);
$class = isset($_module[1])?$_module[1]:MODULE_NAME.'Action';
$module = new $class;
}else{
// 是否定义Empty模块
$module = A("Empty");
}
if(!$module) {
// 模块不存在 抛出异常
throw_exception(L('_MODULE_NOT_EXIST_').MODULE_NAME);
}
}

//获取当前操作名
$action = ACTION_NAME;
if(strpos($action,':')) {
// 执行操作链 最多只能有一个输出
$actionList = explode(':',$action);
foreach ($actionList as $action){
$module->$action();
}
}else{
if (method_exists($module,'_before_'.$action)) {
// 执行前置操作
call_user_func(array(&$module,'_before_'.$action));
}else{
// 操作前置标签
if($tagOn) tag('action_before');
}
//执行当前操作
call_user_func(array(&$module,$action));
if (method_exists($module,'_after_'.$action)) {
// 执行后缀操作
call_user_func(array(&$module,'_after_'.$action));
}else{
// 操作后置标签
if($tagOn) tag('action_after');
}
}
// 项目结束标签
if($tagOn) tag('app_end');
return ;
}


根据上面代码,
首先创建Action控制器实例$module = A(MODULE_NAME),
其中function A()是在文件functions.php里的,它负责实例化对应的Action的class,它的部分代码如下,它根据MODULE_NAME来加载对应的Ation Class的文件,之后通过$action = new $className()进行实例化.

if('@'===$appName) {
require_cache(LIB_PATH.'Action/'.$className.'.class.php');
}else{
import($appName.'.Action.'.$className);
}
if(class_exists($className)) {
$action = new $className();
$_action[$appName.$OriClassName] = $action;
return $action;
}else {
return false;
}


后记:由于看得文档时ThinkPHP2.0的,而所有的代码都是ThinkSNS1.6(使用的是ThinkPHP1.6)的,所以有些地方并不是很准确,但大体思想和步骤是一致的。
分享到:
评论

相关推荐

    Thinkphp执行流程.ppt

    《ThinkPHP执行流程详解》 ThinkPHP是一款广受欢迎的PHP开发框架,它的高效性和灵活性使得开发者能够快速构建高质量的Web应用。本文将深入解析ThinkPHP的执行流程,从访问index.php到加载Action文件、调用用户指定...

    Thinkphp执行流程

    《深入理解Thinkphp执行流程》 Thinkphp是一个广泛使用的PHP框架,它的执行流程对于开发者来说至关重要,因为它决定了代码如何被解析、执行以及控制流程。本文将深入探讨Thinkphp的执行流程,从入口文件开始,逐步...

    ThinkPHP执行流程分析

    《ThinkPHP执行流程详解》 ThinkPHP是一款广受欢迎的PHP框架,它的设计思想在于简化开发,提高效率。本文将深入解析ThinkPHP的执行流程,帮助开发者理解从访问index.php到加载Action文件、调用用户指定操作的具体...

    ThinkPHP执行流程

    ThinkPHP的执行流程CHM帮助文档

    THINKPHP3.0执行流程图PDF

    ### THINKPHP3.0执行流程详解 #### 一、项目启动与初始化 THINKPHP3.0是一款基于PHP的轻量级开发框架,其执行流程是理解整个框架工作原理的关键。从项目入口文件(index.php)开始,THINKPHP3.0会依次经过多个阶段...

    thinkPhp 资料大全---下载不扣分,回帖加1分,欢迎下载,童叟无欺

    ThinkPHP执行流程(1).chm ThinkPHP执行流程.chm ThinkPHP数据操作指南(1).chm ThinkPHP数据操作指南.chm ThinkPHP模板指南.chm ThinkPHP类库导入和自动加载.chm ThinkPHP编码规范.chm ThinkPHP表单令牌设计....

    Thinkphp框架执行流程图.pdf

    根据给定文件内容,可以总结出ThinkPHP框架的执行流程如下: 1. 用户发起URL请求。 2. Web服务器接收到请求,调用应用入口文件(通常是网站的index.php)。 3. 在index.php文件中载入ThinkPHP框架的入口文件...

    Think php 的技術手冊

    这是一个很方便的技术手册包括 ThinkPHP_URL设计和SEO支持 ThinkPHP_错误调试和日志 ThinkPHP_基于角色的权限控制 ThinkPHP_基于角色的权限控制 ThinkPHP1.6.0RC1快速入门 ThinkPHP2.0完全开发手册 ...ThinkPHP执行流程

    thinkPHP开发流程图

    ### ThinkPHP 开发流程详解 #### 一、ThinkPHP启动过程概述 ThinkPHP是一个非常流行的PHP框架,以其高效、简洁的特性受到了众多开发者的青睐。本文将基于“ThinkPHP开发流程图”对ThinkPHP的启动过程进行详细解析...

    基于thinkphp5框架的定时执行任务

    以上就是使用ThinkPHP5框架实现定时任务的基本流程。通过这种方式,你可以灵活地控制何时执行哪些任务,以及它们的执行频率。此外,你还可以根据实际需求,扩展更多的行为来处理更复杂的任务,如任务队列、异步任务...

    基于thinkphp框架的定时器(定时执行任务)

    定时任务,也称为Cron Job,在服务器环境中常用于定期执行某些脚本或程序,以实现自动化工作流程。ThinkPHP中的定时任务功能,可以帮助开发者在设定的时间点自动触发某些业务逻辑,提高工作效率,减少手动干预。 二...

    ThinkPHP_v5.0.7.zip_ThinkPHP V5.0.7_thinkphp

    它采用模块化设计,使得项目结构清晰,代码组织有序,大大简化了开发流程。同时,该框架支持自动路由和控制器绑定,这使得URL调度更加灵活,提高了系统的可扩展性。 其次,ThinkPHP V5.0.7引入了依赖注入...

    ThinkPHP5快速入门手册

    本快速入门手册通过循序渐进的方式介绍了ThinkPHP5.0的基础使用,包括安装、配置和基本开发流程。对于想入门ThinkPHP的开发者来说,这是一个非常好的学习资源。手册中也提到了ThinkPHP的目录结构、运行环境、入口...

    ThinkPHP6.0.zip

    8. **命令行工具**:ThinkPHP6.0的命令行工具(Artisan)允许开发者执行各种任务,如生成控制器、模型、迁移等,提高了开发效率。 9. **单元测试**:内置的PHPUnit支持,方便开发者进行单元测试,确保代码质量。 ...

    thinkphp作业.zip

    ThinkPHP是中国非常流行的一个开源PHP框架,它提供了MVC(模型-视图-控制器)模式,简化了Web应用的开发流程,支持快速开发、稳定性和安全性。 【文件名称列表】 1. "响应式Thinkphp仓库进销管理系统源码" 这个...

    thinkphp项目婚庆商城

    3. 数据库操作:ThinkPHP内置了强大的数据库操作类,支持SQL语句的动态构造和执行,方便进行数据查询、增删改等操作。 4. 错误和日志管理:通过ThinkPHP的异常处理机制和日志记录,可以及时发现和定位问题,提高系统...

    ThinkPHP5.1【官方下载】

    3. **中间件**:ThinkPHP5.1引入了中间件机制,允许开发者在请求处理流程中插入自定义逻辑,如日志记录、权限验证等,增强了系统的灵活性和模块化。 4. **错误和异常处理**:提供了完善的错误和异常处理机制,便于...

    ThinkPHP多语言检测行为扩展插件包

    行为扩展(Behavior)是ThinkPHP框架中的一个重要概念,它是一种可以插入到模型操作流程中的自定义代码,允许开发者在特定的事件点执行自定义逻辑。这个“CheckLangBehavior”类就是这样一个行为扩展,它会在特定...

    Thinkphp6完整资源包下载

    `think` 是ThinkPHP6的命令行工具,用于执行各种命令行操作,如创建控制器、模型等,极大地方便了开发过程。 `LICENSE.txt` 文件包含了项目的授权协议,ThinkPHP6遵循Apache2.0开源协议,允许商业和个人自由使用、...

Global site tag (gtag.js) - Google Analytics