thinkphpnewapp(),ThinkPHP5源码分析之App(3)
App类可以说是总框架的第⼆个真正⼊⼝了,所有的框架逻辑操作都在这⾥完成。这也是为什么我要把他提在其他核⼼组件类之前分析的原因。我们先看⼊⼝⽂件start.php代码:
require __DIR__ . '/base.php';
App::run()->send();
base.php在第⼀章⾥已经说了,做了前期的准备⼯作(定义系统必要的常量以及注册⾃动加载),然后就执⾏App的run然后send。这篇就说下⼀个请求从开始到结束的整个流程run做了什么,主要涉及到Request、route。也建议⼤家先看下base.php定义的常量以及config配置。这⾥是官⽅给出的更详细的参考⽂档:
PS:下⽂提到EXT均为⽂件后缀定义,TP为当前讲述的框架
对app::run()做⼀个流程性的总结阐述:
流程代码有做精简,略去业务性的判断以及更好展现流程代码优化
1.1、加载当前模块(module)下的初始化⽂件({$module}init.EXT)在我理解,(我觉得这个⽂件官⽅意图是希望我们框架使⽤者将其他的⼀些功能性的配置⽂件以及⾃定义⼀些必要的内容进⾏⼀个集合式的加载。当如如果这个⽂件不存在直接读取其下⾯指定的⽂件)见代码:
init($module = '') {
is_file($current_module . 'init' . EXT) {
//这玩意其实可以⾃定义的将下⾯这些东西整合起来打包
include $module . 'init' . EXT;
} else {
$config = Config::load($module . 'config' . CONF_EXT);
//app状态环境的⼀个配置开发环境、⽣产环境、测试环境等不同配置
if ($config['app_status']) {
$config = Config::load($module . $config['app_status'] . CONF_EXT);
}
//读取扩展配置⽂件 当然你必须在$config⾥⾯定义了extra_config_list
foreache($config['extra_config_list'] as $config){
Config::load($module . $config . CONF_EXT);
}
//加载别名⽂件 $module . 'alias' . EXT
Loader::addClassMap(include $module . 'alias' . EXT);
//加载⾏为扩展⽂件
Hook::import($module . 'tags' . EXT);
加载别名⽂件
include $module. 'common' . EXT;
/
/加载语⾔包
return Config::get();
}
1.2、读取配置⾥⾯的也就是1.1的配置命名空间相关配置、额外其他⽂件进⾏加载见代码:
initCommon(){
$config = self::init();
//调试模式设置
self::$debug = Config::get('app_debug');
…………
//命名空间加载(这⾥说下这⾥加载是对命名空间⾃定义简化或者其他想法进⾏的⼀个key=>value配置加载) Loader::addNamespace($config['app_namespace'], APP_PATH);
//设置系统时区
date_default_timezone_set($config['default_timezone']);
self::$init = $config;
return self::$init;
}
2、根据请求URL以及配置config分析出调度信息(也就是当前操作状态、模块、控制器、操作、参数)
run(Request $request = null){
//单例个Request对象
is_null($request) && $request = Request::instance();
//这个就是 part1 了
$config = self::initCommon();
try {
/
/多语⾔
Lang::load(THINK_PATH . 'lang' . DS . $request->langset() . EXT);
//获取调度信息 这个Request就是刚才的对象 准备去routeCheck⾥⾯⼲⼤事去
/*
routcheck返回的调度信息⼤致这样的 当然type是正常请求controller/action 其他类型后讲
$dispatch = [
'type' => 'module',
'module' => [
{$module}, {$controller}, {$action.$params}
]
$check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
}
}
routeCheck($request, array $config){
……
//Request::path获取http $_SERVER以及根据config配置参数进⾏处理
/*
$path = '{$module}/{$controller}/{$action}?{$param1}={$val1}&{$param2}={$val2}……'
*/
$path = $request->path();
//pathinfo 定义的分隔符 去补习⼿册配置吧
$depr = $config['pathinfo_depr'];
$result = false;
//路由检测
$check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
if($check) {
//路由配置导⼊
Route::import($config['route']);
//路由检测 详细见Route类源码分析
$result = Route::check($request, $path, $depr, $config['url_domain_deploy']);
//强制⾛路由配置
$must = $config['url_route_must'];
if ($must && false === $result) {
//GG……route not found
}
}
if (false === $result) {
// 路由⽆效 解析模块/控制器/操作/参数... ⽀持控制器⾃动搜索 就是对请求url进⾏按照规则进⾏整理 详route类$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
}
return $result;
3、进⾏分发调度执⾏。
run(Request $request = null){
is_null($request) && $request = Request::instance();
$config = self::initCommon();
try {
Lang::load(THINK_PATH . 'lang' . DS . $request->langset() . EXT);
$dispatch = self::routeCheck($request, $config);
……
thinkphp3
switch($dispatch['type']){
……
//进⾏请求调度
case 'module':
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null); break;
……
default:
throw new \InvalidArgumentException('dispatch type not support');
}catch (HttpResponseException $exception) {
$data = $exception->getResponse();
}
Loader::clearInstance();
……
return $response;
}
}
下⼀章会着重App::module进⾏分析,会穿插Route相关内容。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。