ThinkPHP源码解读1
1.Thinkphp我们可以设置一个入口文件index.php,然后在入口文件中引入Thinkphp框架的入口文件,原则上项目的入口文件可以放到任意处;
2. ThinkPHP框架的入口文件大概做两个事情,一是定义目录的常量,二是启动核心类think的start方法;
3.TP框架的大部分初始化都是在start方法中进行的;一个重要的步骤是加载核心文件,加载哪些文件呢?可以通过自己配置(/Application/Common/Conf/core.php),也可以用默认的方式(ThinkPHP/Mode/common.php");得到数组,遍历加载进来就是了;
4.只有加载进来这些核心文件,我们才能用框架定义的函数A,C,D,数据库类,控制器类等等。
5.继续执行app类(ThinkPHP/Library/Think/App.class.php)的run方法,这个类上一步已经加载进来了
.
5.1 Hook::listen(‘app_init’)会执行app_init标签绑定的behavior的run方法,我们可以通过配置来自己实现这个run方法,可以查看https://blog.csdn.net/littlexiaoshuishui/article/details/93741742;App::init();先动态加载项目公共目录下的文件(/Application/Common/),load_ext_file(Application/Common),会把目录里面的配置了外部文件加载进来,例如在/Application/Common/配置db.php,用作数据库的配置文件。
这种配置多个配置文件的原理就是,在/Application/Common/config中配置‘LOAD_EXT_CONFIG’=>‘db‘, 多个配置文件就用逗号隔开,就能加载common/business.php, common/db.php
5.2 App::init() 也调用Dispatcher::dispatch()做url调度
thinkphp经常用了url重新功能,项目根目录下有.htaccess文件,例如:http://localhost/wxjza/Root/Home/Test/test
<IfModule mod_rewrite.c>Options +FollowSymlinksRewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
</IfModule>
在Dispatcher::dispatch() 中,打印出$_GET['s'] = "/Home/Test/test"; 获取到url路径中的参数,然后赋值给$_SERVER['PATH_INFO'];
处理PATHINFO信息,获取路径后缀给常量__EXT__; 获取模块名给MODULE_NAME;
define('__INFO__',trim($_SERVER['PATH_INFO'],'/'));// URL后缀define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION)));$_SERVER['PATH_INFO'] = __INFO__; if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){if (__INFO__ && C('MULTI_MODULE')){ // 获取模块名$paths = explode($depr,__INFO__,2);$allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表$module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]);if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){$_GET[$varModule] = $module;$_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:'';}}} }// URL常量define('__SELF__',strip_tags($_SERVER[C('URL_REQUEST_URI')]));// 获取模块名称define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule));
检测模块路径,加载改模块下的配置文件,该模块下在函数等等
// 检测模块是否存在if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){// 定义当前模块路径define('MODULE_PATH', APP_PATH.MODULE_NAME.'/');// 定义当前模块的模版缓存路径C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/');// 定义当前模块的日志目录C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/');// 模块检测Hook::listen('module_check');// 加载模块配置文件if(is_file(MODULE_PATH.'Conf/config'.CONF_EXT))C(load_config(MODULE_PATH.'Conf/config'.CONF_EXT));// 加载应用模式对应的配置文件if('common' != APP_MODE && is_file(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT))C(load_config(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT));// 当前应用状态对应的配置文件if(APP_STATUS && is_file(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT))C(load_config(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT));// 加载模块别名定义if(is_file(MODULE_PATH.'Conf/alias.php'))Think::addMap(include MODULE_PATH.'Conf/alias.php');// 加载模块tags文件定义if(is_file(MODULE_PATH.'Conf/tags.php'))Hook::import(include MODULE_PATH.'Conf/tags.php');// 加载模块函数文件if(is_file(MODULE_PATH.'Common/function.php'))include MODULE_PATH.'Common/function.php';$urlCase = C('URL_CASE_INSENSITIVE');// 加载模块的扩展配置文件load_ext_file(MODULE_PATH);}else{E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME);}
然后用类似的方法,获取到控制器CONTROLLER_NAME,方法ACTION_NAME,还有url的参数$_GET,此时,url调度完毕;
5.3 App::init() 最后是过滤$_GET,$_POST,$_REQUEST,过滤的方法是think_filter().还有判断是否是ajax请求;
// URL调度Dispatcher::dispatch();if(C('REQUEST_VARS_FILTER')){// 全局安全过滤array_walk_recursive($_GET, 'think_filter');array_walk_recursive($_POST, 'think_filter');array_walk_recursive($_REQUEST, 'think_filter');}// URL调度结束标签Hook::listen('url_dispatch'); define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false);
5.4 然后是执行App::exec();映射需要执行的方法,执行对应的方法
//执行当前操作$method = new \ReflectionMethod($module, $action);
最终都是通过php的映射类来调用我们的控制器方法的;
Thinkphp框架启动的大致流程就是这样啦。
ThinkPHP源码解读1相关推荐
- ThinkPhp 源码解读 Model篇
ThinkPhp 源码解读 Model篇 本篇主要讲解TP下 Model Query Connection DB Builder 类的关系 最终理解 model('xxx')->startTra ...
- thinkphp源码解读
thinkphp源码解读 thinkphp源码的根目录下是 index.php,是系统默认的 主页,index.php中首先检测的是 php运行环境,如果php版本小于 5.3.0则退出执行, 定义是 ...
- Bert系列(二)——源码解读之模型主体
本篇文章主要是解读模型主体代码modeling.py.在阅读这篇文章之前希望读者们对bert的相关理论有一定的了解,尤其是transformer的结构原理,网上的资料很多,本文内容对原理部分就不做过多 ...
- Bert系列(三)——源码解读之Pre-train
https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...
- linux下free源码,linux命令free源码解读:Procps free.c
linux命令free源码解读 linux命令free源码解读:Procps free.c 作者:isayme 发布时间:September 26, 2011 分类:Linux 我们讨论的是linux ...
- nodeJS之eventproxy源码解读
1.源码缩影 !(function (name, definition) { var hasDefine = typeof define === 'function', //检查上下文环境是否为AMD ...
- PyTorch 源码解读之即时编译篇
点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 作者丨OpenMMLab 来源丨https://zhuanlan.zhihu.com/ ...
- Alamofire源码解读系列(九)之响应封装(Response)
本篇主要带来Alamofire中Response的解读 前言 在每篇文章的前言部分,我都会把我认为的本篇最重要的内容提前讲一下.我更想同大家分享这些顶级框架在设计和编码层次究竟有哪些过人的地方?当然, ...
- Feflow 源码解读
Feflow 源码解读 Feflow(Front-end flow)是腾讯IVWEB团队的前端工程化解决方案,致力于改善多类型项目的开发流程中的规范和非业务相关的问题,可以让开发者将绝大部分精力集中在 ...
最新文章
- JAVA框架Struts2 Action类
- android中layout、drawable及styles的xml文件加载探索
- zoom怎么解除静音_ZOOM视频软件使用指南(学生端)
- Java并发编程实战————并发技巧小结
- mysql8.0免安教程图解,mysql 8.0.21免安装版配置方法图文教程
- 在c#中用mutex类实现线程的互斥_C# 多线程系列(4)进程同步Mutex类
- 【MySQL】MySQL RROR! The server quit without updating PID file
- 【物联网中间件平台-03】YFIOs安装指南
- php 获取文件加的名称
- 安装 配置BlackBerry Push Service SDK v1.1.0
- java工程源码看不懂_目前从事java开发工作,看不懂源码应该怎么做?
- python列表append方法_Python列表append()方法
- curl指定代理_如何使用cURL指定用户代理
- PayPal取消了连连支付快捷提现,我是如何提现到国内的?
- 【python实例】判断是否为酒后驾车
- AnyPi智能语音音箱方案 智能蓝牙WIFI音箱方案开发 DuerOS及Alexa平台
- 如何高逼格的写java代码
- 在服务器上安装jdk
- 为什么我要用 Node.js? 案例逐一介绍
- xgboost学习样例解析之binary classification