ThinkPHP框架系统源码解析——URL路由解析

  1 一、ThinkPHP框架目录
  2 /test/index.php //项目入口文件
  3 /ThinkPHP/ThinkPHP.php //框架入口文件
  4
  5 Common 框架公共文件目录(函数库)
  6 ThinkPHP/Common/runtime.php //框架初次运行文件
  7 ThinkPHP/Common/common.php //框架基础函数库
  8 ThinkPHP/Common/functions.php //标准模式公共函数库
  9
 10 Conf 框架配置文件目录
 11 ThinkPHP/Conf/convention.php  //惯例配置文件,系统默认配置小于项目配置
 12 ThinkPHP/Conf/debug.php //默认的调试模式配置文件
 13
 14 Lang 框架系统语言目录
 15
 16 Lib 系统核心基类库目录
 17 ThinkPHP/Core/Think.class.php //入口文件(设置异常和错误处理机制、注册系统自动加载机制、预编译当前项目、加载框架惯例配置文件)
 18 ThinkPHP/Lib/Core/Log.class.php,    // 日志处理类
 19 ThinkPHP/Lib/Core/Dispatcher.class.php, // URL调度类
 20 ThinkPHP/Lib/Core/App.class.php,   // 应用程序类
 21 ThinkPHP/Lib/Core/Action.class.php, // 控制器类
 22 ThinkPHP/Lib/Core/View.class.php,  // 视图类
 23
 24 Tpl 系统模板目录
 25 ThinkPHP/Tpl/default_index.tpl //测试模块的模板
 26 ThinkPHP/Tpl/dispatch_jump.tpl //页面提示的模板
 27 ThinkPHP/Tpl/page_trace.tpl //页面Trace信息的模板
 28 ThinkPHP/Tpl/think_exception.tpl //系统错误信息的模板
 29
 30 Extend 框架扩展目录
 31
 32
 33 <?php
 34 /*
 35  * 1、用户访问网站URL地址
 36  * /test/Index.php 项目入口文件
 37  */
 38 require (‘../ThinkPHP/ThinkPHP.php‘);//引入框架文件
 39
 40
 41
 42
 43 /*
 44  * 2、载入系统入口文件ThinkPHP.php
 45  * ThinkPHP/ThinkPHP.php框架入口文件
 46  * 判断系统常量,如果没有定义则自动生成
 47  */
 48 $GLOBALS[‘_beginTime‘] = microtime(TRUE); //记录运行时的时间
 49
 50
 51 define(‘MEMORY_LIMIT_ON‘,function_exists(‘memory_get_usage‘));//php中用echo memory_get_usage() 获取当前的内存消耗量
 52
 53
 54 if(MEMORY_LIMIT_ON) $GLOBALS[‘_startUseMems‘] = memory_get_usage();//如果支持内存使用量函数则全局变量$GLOBALS[‘_startUseMems‘]等于内存使用量,这里相当于记录下内存初始使用的量
 55
 56
 57 defined(‘APP_PATH‘) or define(‘APP_PATH‘, dirname($_SERVER[‘SCRIPT_FILENAME‘]).‘/‘);//设置当前的项目路径
 58
 59
 60 defined(‘RUNTIME_PATH‘) or define(‘RUNTIME_PATH‘,APP_PATH.‘Runtime/‘);//设置runtime的路径
 61
 62
 63 defined(‘APP_DEBUG‘) or define(‘APP_DEBUG‘,false); // 是否调试模式,默认false
 64
 65
 66 $runtime = defined(‘MODE_NAME‘)?‘~‘.strtolower(MODE_NAME).‘_runtime.php‘:‘~runtime.php‘;//如果设置了其它运行模式则~ruturn.php就变化为 ~模式ruturn.php,(例如,采用命令行模式运行),那么在入口文件中定义MODE_NAME如下define(‘MODE_NAME‘,‘cli‘);  那么这里的缓存文件就为~cliruturn.php
 67
 68
 69 defined(‘RUNTIME_FILE‘) or define(‘RUNTIME_FILE‘,RUNTIME_PATH.$runtime);//设置~runtime.php的路径;
 70
 71
 72 if(!APP_DEBUG && is_file(RUNTIME_FILE)) {
 73     // 部署模式直接载入运行缓存
 74     require RUNTIME_FILE;
 75 }else{//高度模式下加载框架下的Common/runtime.php文件;我们就模拟程序第一次运行,从下面开始进入
 76     // 系统目录定义
 77     defined(‘THINK_PATH‘) or define(‘THINK_PATH‘, dirname(__FILE__).‘/‘);
 78     // 加载运行时文件,载入系统运行时文件runtime.php并定义项目路径常量
 79     require THINK_PATH.‘Common/runtime.php‘;
 80 }
 81
 82 /*
 83  * 3、载入系统运行时文件runtime.php并定义项目路径常量
 84  * ThinkPHP/Common/runtime.php 系统运行时文件
 85  * ThinkPHP 运行时文件 编译后不再加
 86  */
 87
 88
 89 //从18——81行定义了程序中要用到的各种常量
 90
 91
 92 //#84行  为了方便导入第三方类库 设置Vendor目录到include_path
 93 set_include_path(get_include_path() . PATH_SEPARATOR . VENDOR_PATH);//这一句将/ThinkPHP/Extend/Vendor/ 加入了include_path目录中
 94
 95
 96 //#87-114行 加载运行时所需要的文件 并负责自动目录生成
 97 function load_runtime_file() {
 98 //引入/ThinkPHP/Lib/Core/Think.class.php
 99 //引入/ThinkPHP/Lib/Core/ThinkException.class.php,  // 异常处理类
100 //引入/ThinkPHP/Lib/Core/Behavior.class.php,
101 // 检查项目目录结构 如果不存在则自动创建   build_app_dir();check_runtime();
102
103
104 }
105
106
107 //#118-130行 // 检查缓存目录(Runtime) 如果不存在则自动创建
108 function check_runtime() {
109 // 在load_runtime_file()中被引用
110 }
111
112
113 //#133-163行 //创建编译缓存
114 function build_runtime_cache($append=‘‘) {
115 //没仔细研究,是把程序中用到的代码都压入到~return.php缓存文件中
116 }
117
118
119 //#164-174 //// 编译系统行为扩展类库
120 function build_tags_cache() {
121 //编译系统行为扩展类库 compile($filename)此函数
122 }
123
124
125 //117-224 // 创建项目目录结构
126 function build_app_dir(){
127 //创建项目目录结构
128 }
129
130
131 //227-230 // 创建测试Action
132 function build_first_action(){
133 // /ThinkPHP/Tpl/default_index.tpl模板
134 }
135
136
137 //#233 加载运行时所需文件
138 load_runtime_file();
139
140
141 //#235 记录加载文件时间
142 G(‘loadTime‘);
143
144
145 // 执行入口
146 Think::Start();
147
148
149 /*
150 * 执行入口
151 * /ThinkPHP/Lib/Core/Think.class.php
152 * 程序的入口(设置异常和错误处理机制、注册系统自动加载机制、预编译当前项目、加载框架惯例配置文件)
153 */
154
155
156 //#37-49 应用程序初始化
157 static public function Start() {
158         // 设定错误和异常处理
159         set_error_handler(array(‘Think‘,‘appError‘)); //将this->appError()注册为错误处理方法
160         set_exception_handler(array(‘Think‘,‘appException‘)); //将$this->appException()注册为异常处理函数
161         // 注册AUTOLOAD方法
162         spl_autoload_register(array(‘Think‘, ‘autoload‘));//将$this->autoload()注册为__autoload()方法
163         //[RUNTIME]
164         Think::buildApp();         // 读取配置信息 预编译项目
165         //[/RUNTIME]
166         // 运行应用
167         App::run();
168         return ;
169 }
170
171
172 //#61-124 读取配置信息 预编译项目
173 static private function buildApp() {
174     // /ThinkPHP/Conf/convention.php 读取系统配置,读取项目配置 /项目/Conf/conf.php 合并配置
175     //加载语言包(可能是支持多语言的,目前没用到过)
176     //加载模式系统行为定义(没看明白)
177     //读取核心编译文件列表 (使用compile()函数,将所有核心类及函数、自定义类库压入到$compile变量中,等待编译~runtime.php)
178     (
179         ThinkPHP/Common/functions.php, // 标准模式函数库
180         ThinkPHP/Lib/Core/Log.class.php,    // 日志处理类
181         ThinkPHP/Lib/Core/Dispatcher.class.php, // URL调度类
182         ThinkPHP/Lib/Core/App.class.php,   // 应用程序类
183         ThinkPHP/Lib/Core/Action.class.php, // 控制器类
184         ThinkPHP/Lib/Core/View.class.php,  // 视图类
185     );
186     // ThinkPHP/Common/common.php //加载项目公共文件(函数库)
187     // 项目/Conf/alias.php 加载项目别名定义(项目自定义类库,用别名导入的方式引入的自定义类库)
188     // 如果是调试模式,加载系统默认的配置文件ThinkPHP/Conf/debug.php的默认调试配置,如果项目自己定义了 项目/Conf/debug.php则读取项目调试配置
189     // 最后如果是部署模式 使用build_runtime_cache($compile); 创建编译缓存,将$compile变量写入到项目/Runtime/~runtime.php文件中
190     // 欧克至此该引入的文件全部引入完成,下面讲解控制器篇
191     // 最后的最后我们来回顾一下我们加载了些什么东西到程序中来
192     /*
193     * 1、ThinkPHP/Common/functions.php, // 标准模式函数库
194     * 2、ThinkPHP/Lib/Core/Log.class.php,    // 日志处理类
195     * 3、ThinkPHP/Lib/Core/Dispatcher.class.php, // URL调度类
196     * 4、ThinkPHP/Lib/Core/App.class.php,   // 应用程序类
197     * 5、ThinkPHP/Lib/Core/Action.class.php, // 控制器类
198     * 6、ThinkPHP/Lib/Core/View.class.php,  // 视图类
199     * 7、ThinkPHP/Common/common.php //加载项目公共文件(函数库)
200     * 8、项目/Conf/alias.php 加载项目别名定义(项目自定义类库,用别名导入的方式引入的自定义类库)
201     * 9、ThinkPHP/Conf/debug.php的默认调试配置
202     */
203 }
204
205
206 /*
207 * 加载了半天文件再在来真的了,正式进入程序运行 App::run();
208 * /ThinkPHP/lib/Core/App.class.php //应用程序类 执行应用过程管理
209 * 这里是整个程序的入口,我们要跳着读,首先跳入App::init();
210 * 最后一步跳入App::exec();
211 */
212
213
214 // #148-164 运行应用实例 入口文件使用的快捷方法
215
216
217     static public function run() {
218         // 项目初始化标签
219         tag(‘app_init‘);
220         App::init();
221         // 项目开始标签
222         tag(‘app_begin‘);
223         // Session初始化
224         session(C(‘SESSION_OPTIONS‘));
225         G(‘initTime‘);
226         //执行应用程序
227         App::exec();
228         // 项目结束标签
229         tag(‘app_end‘);
230         // 保存日志记录
231         if(C(‘LOG_RECORD‘)) Log::save();
232         return ;
233     }
234
235
236 // #36-76 应用程序初始化
237  static public function init() {
238     // load_ext_file(); 加载动态项目公共文件和配置
239     // URL调度 Dispatcher::dispatch(); //进入Thinkphp/lib/Core/Dispatcher.class.php dispatch()方法,进行URL参数常量赋值
240     // 如果有分组,include 分组配置与函数文件
241     // 获取模板主题名称 $templateSet = C(‘DEFAULT_THEME‘);
242     // 定义模板路径常量 define(‘THEME_PATH‘,   TMPL_PATH.$group.(THEME_NAME?THEME_NAME.‘/‘:‘‘));
243     // 定义模板路径常量 define(‘APP_TMPL_PATH‘,__ROOT__.‘/‘.APP_NAME.(APP_NAME?‘/‘:‘‘).basename(TMPL_PATH).‘/‘.$group.(THEME_NAME?THEME_NAME.‘/‘:‘‘));
244     // 定义模板文件的位置 C(‘TEMPLATE_NAME‘,THEME_PATH.MODULE_NAME.(defined(‘GROUP_NAME‘)?C(‘TMPL_FILE_DEPR‘):‘/‘).ACTION_NAME.C(‘TMPL_TEMPLATE_SUFFIX‘));
245     // 定义模板文件缓存的位置 C(‘CACHE_PATH‘,CACHE_PATH.$group);
246  }
247
248
249 // #89-138 执行应用程序
250  static public function exec() {
251     // 安全检测,模块名必须是英文和数字组成,且英文为首
252     // 检测通过 实例化 控制器 $module  =  A($group.MODULE_NAME);
253     // 检测如果定义了__hack_module()扩展,则遇到当前模块不存在时会被接管,优先级大于空模块EmptyAction
254     // 检测如果否定义空模块EmptyAction,则遇到不存在模块时调用EmptyAction模块
255     // 检测前置后置方法(_before_、_after_) method_exists($module,‘_before_‘.$action),如果有则执行 call_user_func(array(&$module,‘_before_‘.$action));
256     // 亮点在这里,至此URL解析完成了,跳转到 某某模块下的某某方法 执行当前操作 call_user_func(array(&$module,$action));
257  }
258
259 /*
260 * 接上一步,跳入App::init();后,我们发现需要跳入Dispatcher::dispatch();URL调度类中进行URL参数常量赋值,下面带你进入Disppatcher::dispatch方法中进行常量赋值
261 * ThinkPHP内置的Dispatcher类 只提供了一个公共的静态方法dispatch()方法作为接口,本方法将路由变量压入到常量中,供后面的action类使用
262 * 完成URL解析、路由和调度
263 * ThinkPHP/lib/Core/Dispatcher.class.php
264 * 完成后跳回到App::init();
265 */
266
267
268 //#36-153 URL映射到控制器
269 static public function dispatch() {
270     //C(‘URL_MODEL‘);读取URL模式
271     //将模块提取到MODULE_NAME全局变量中,将动作提取到ACTION_NAME全局变量中,将参数
272     // $paths = explode($depr,trim($_SERVER[‘PATH_INFO‘],‘/‘));//解析path_info
273     //$var[C(‘VAR_MODULE‘)]  =   array_shift($paths);//提取模块
274     // $var[C(‘VAR_ACTION‘)]  =   array_shift($paths);//提取方法
275     // $_GET   =  array_merge($var,$_GET);//重写$_GET
276     // pathinfo常量 __INFO__
277     // 控制器常量 define(‘MODULE_NAME‘,self::getModule(C(‘VAR_MODULE‘)));
278     // 方法常量 define(‘ACTION_NAME‘,self::getAction(C(‘VAR_ACTION‘)));
279     // URL常量 define(‘__SELF__‘,strip_tags($_SERVER[‘REQUEST_URI‘]));
280     // 当前项目地址常量 define(‘__APP__‘,strip_tags(PHP_FILE));
281     // 当前操作地址常量 define(‘__ACTION__‘,__URL__.$depr.ACTION_NAME);
282     // $_REQUEST = array_merge($_POST,$_GET); $_REQUEST重写
283 }
284
285
286 //注:获取系统配置用C()方法,此方法写得很巧妙,建议大家看一下
时间: 2024-10-11 00:04:47

ThinkPHP框架系统源码解析——URL路由解析的相关文章

Yii源码阅读笔记 - 路由解析

2014-11-12 三 By youngsterxyf 概述 Yii框架的路由解析功能由核心组件urlManager来完成.路由的形式有两种: get:通过URL中查询字符串(query string)参数r来指定路由,如:r=controllerID/actionID path:直接通过URL来指定,如:/controllerID/actionID 默认使用get路由形式.由于Yii中controller类命名和action方法都是按照规则命名的,而路由也是按照规则来匹配的,所以完全可以不用

Qt元对象系统源码解析

Qt元对象系统源码解析 https://blog.51cto.com/9291927/2070348 一.Qt元对象系统简介 1.元对象系统简介 Qt 的信号槽和属性系统基于在运行时进行内省的能力,所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力, 比如如果语言具有运行期间检查对象型别的能力,那么是型别内省(type intropection)的,型别内省可以用来实施多态.C++的内省比较有限,仅支持型别内省, C++的型别内省是通过运行时类型识别(RTTI)(Run-Time Typ

Android 图片加载框架Universal-Image-Loader源码解析

Universal-Image-Loader(项目地址)可以说是安卓知名图片开源框架中最古老.使用率最高的一个了.一张图片的加载对于安卓应用的开发也许是件简单的事,但是如果要同时加载大量的图片,并且图片用于ListView.GridView.ViewPager等控件,如何防止出现OOM.如何防止图片错位(因为列表的View复用功能).如何更快地加载.如何让客户端程序员用最简单的操作完成本来十分复杂的图片加载工作,成了全世界安卓应用开发程序员心头的一大难题,所幸有了Universal-Image-

仿百度经验,经验网站系统源码,菜谱网站系统源码

10年的技术团队专业定制仿百度经验,经验网站系统源码,菜谱网站系统源码该经验系统由绿茶科技团队自主开发,系统采用了国内比较主流的thinkPHP框架实现的,数据库用MySQL.是一套类似百度经验,菜谱网站系统,具有清晰的步骤流程功能,是目前国内少有的网站系统.模版设计整洁.清爽,广告位布局合理.会员积分体系完善,支持用户上传分享免费.收费资源.下载收益支持用户提现.分享有收益,刺激用户上传扩充网站资源,实现商家与平台联和共盈. PC版:   手机版:    服务器选择:  服务器购买地址:htt

fcontex博客系统源码

fcontex是开源的PHP博客系统,拥有漂亮的Web 2.0风格的后台界面和完全Ajax化的流畅操作体验,可用于快速构建中小型企业网站和个人博客(Blog).fcontex是专为二次开发而设计的,主要体现在以下两点:1.基于完全模块化方式设计和开发,且仿照内置模块能快速上手fcontex模块开发:2.基于dispatcher.php主题定制文件,可以实现任意风格的定制主题而不需要改动fcontex的原有代码. fcontex是free和context两个单词的连接简化,寓意自由.流畅的上下文操

如何查看JDK以及JAVA框架的源码

如何查看JDK以及JAVA框架的源码 设置步骤如下: 1.点 “window”-> "Preferences" -> "Java" -> "Installed JRES" 2.此时"Installed JRES"右边是列表窗格,列出了系统中的 JRE 环境,选择你的JRE,然后点边上的 "Edit...", 会出现一个窗口(Edit JRE) 3.选中rt.jar文件的这一项:“c:\pr

第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析

王家林亲授<DT大数据梦工厂>大数据实战视频“Scala深入浅出实战经典”视频.音频和PPT下载!第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析百度云:http://pan.baidu.com/s/1pJ5jzHx腾讯微云:http://url.cn/aSawrm360云盘:http://yunpan.cn/cctL3QYACaVNa  访问密码 c0fb 信息来源于 DT大数据梦工厂微信公众账号:DT_Spark

直播系统源码让您看清现代播放器的架构

随着不同应用场景的增加,直播系统源码定制化功能的需求越来越强.仅仅是直播和点播之间,就存在不同的 buffer 管理.ABR 策略和缓存策略等方面的差别.这些需求催生了一系列更为底层关于多媒体操作 API 的诞生:Flash 上面的 Netstream,HTML5 上的 Media Source Extensions,以及 Android 上的 Media Codec,同时业界又出现了一个基于 HTTP 的标准流格式 MPEG-DASH.这些更高级的能力为开发者提供了更好的灵活性,让他们可以构建

安卓系统源码编译系列(六)——单独编译内置浏览器WebView教程

原文                   http://blog.csdn.net/zhaoxy_thu/article/details/18883015 本文主要对从安卓系统源码中抽取出WebView相关源码进行单独编译的流程进行说明. 编译流程说明 由于WebView包含两个部分,一部分是上层的Java代码,包括若干Java类,用于对外提供接口:另一部分是下层的C++代码,包括两个so库(libwebcore.so和libchromium_net.so),用于网页的解析和渲染.两个部分之间通