栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP > php开源框架 > thinkphp

启动流程 - TP5源代码阅读

thinkphp 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

启动流程 - TP5源代码阅读



[TOC]

* * * * *
#1 启动概述

* 启动的总流程按照文件分为三步
* 1 请求入口(public/index.php)
* 2 框架启动(thinkphp/start.php)
* 3 应用启动 (thinkphp/library/App.php)

#2 入口文件(public/index.php)


// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

> 默认的入口文件在public/index.php
>> 主要定义应用目录,加载框架引导文件(thinkphp/start.php)


#3 框架启动(thinkphp/start.php)

## 3-1 框架引导(thinkphp/start.php)

// 加载基础文件
require __DIR__ . '/base.php';
// 执行应用
App::run()->send();

> 框架引导文件(thinkphp/start.php)
>>主要用来启动框架
>>按照涉及的文件分为以下三步
>>1 定义全局变量与注册自动加载
>>2 加载默认配置
>>3 启动应用

## 3-2 定义全局常量(thinkphp/base.php)

define('THINK_VERSION', '5.0.0');
define('THINK_START_TIME', microtime(true));
define('THINK_START_MEM', memory_get_usage());
define('EXT', '.php');
define('DS', DIRECTORY_SEPARATOR);
defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS);
define('LIB_PATH', THINK_PATH . 'library' . DS);
define('CORE_PATH', LIB_PATH . 'think' . DS);
define('TRAIT_PATH', LIB_PATH . 'traits' . DS);
defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['script_FILENAME']) . DS);
defined('ROOT_PATH') or define('ROOT_PATH', dirname(APP_PATH) . DS);
defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);
defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS);
defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);
defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);
defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);
defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);
defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录
defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀
defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀

// 环境常量
define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
define('IS_WIN', strpos(PHP_OS, 'WIN') !== false);

>>基础文件(thinkphp/base.php)
>>开始部分定义了框架的全局常量
>>包括框架的运行信息,目录组织,运行环境等

## 3-3 注册自动加载(thinkphp/base.php)

// 载入Loader类
require CORE_PATH . 'Loader.php';

// 加载环境变量配置文件
if (is_file(ROOT_PATH . '.env')) {
$env = parse_ini_file(ROOT_PATH . '.env', true);
foreach ($env as $key => $val) {
$name = ENV_PREFIX . strtoupper($key);
if (is_array($val)) {
foreach ($val as $k => $v) {
$item = $name . '_' . strtoupper($k);
putenv("$item=$v");
}
} else {
putenv("$name=$val");
}
}
}

// 注册自动加载
thinkLoader::register();

// 注册错误和异常处理机制
thinkError::register();

>> 基础文件(thinkphp/base.php)
>> 中间部分加载环境配置,
>> 启动自动加载
>> 注册自定义错误与异常处理

## 3-4 加载框架默认配置(thinkphp/convention.php)

thinkConfig::set(include THINK_PATH . 'convention' . EXT);

>>基础文件(thinkphp/base.php)
>>最后加载框架默认配置

## 3-5 框架默认配置(thinkphp/convention.php)

应用设置
模块设置
URL设置
模板设置
异常及错误设置
日志设置
Trace设置
缓存设置
会话设置
cookie设置
数据库设置
分页配置

>>以数组形式实现框架默认配置
>>相关配置信息可以在应用目录(application/)中进行覆盖

#4 应用启动(thinkphp/library/App.php)

## 4-1 请求分析(App.php->run())

App.php;

public static function run(Request $request = null)

is_null($request) && $request = Request::instance();

$config = self::initCommon();
if (defined('BIND_MODULE')) {
// 模块/控制器绑定
BIND_MODULE && Route::bind(BIND_MODULE);
} elseif ($config['auto_bind_module']) {
// 入口自动绑定
$name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
Route::bind($name);
}
}

$request->filter($config['default_filter']);

。。。。。。
}

>> 应用启动的请求分析
>> 首先 创建请求对象(Request)
>> 然后 解析请求的模块信息
>> 最后 过滤请求信息

## 4-2 应用调度(App.php->run())

App.php;

public static function run(Request $request = null)
。。。。。。
try {

// 开启多语言机制
if ($config['lang_switch_on']) {
// 获取当前语言
$request->langset(Lang::detect());
// 加载系统语言包
Lang::load(THINK_PATH . 'lang' . DS . $request->langset() . EXT);
if (!$config['app_multi_module']) {
Lang::load(APP_PATH . 'lang' . DS . $request->langset() . EXT);
}
}

// 获取应用调度信息
$dispatch = self::$dispatch;
if (empty($dispatch)) {
// 进行URL路由检测
$dispatch = self::routeCheck($request, $config);
}
// 记录当前调度信息
$request->dispatch($dispatch);

// 记录路由和请求信息
if (self::$debug) {
Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info');
Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info');
Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
}

// 监听app_begin
Hook::listen('app_begin', $dispatch);

switch ($dispatch['type']) {
case 'redirect':
// 执行重定向跳转
$data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);
break;
case 'module':
// 模块/控制器/操作
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
break;
case 'controller':
// 执行控制器操作
$data = Loader::action($dispatch['controller']);
break;
case 'method':
// 执行回调方法
$data = self::invokeMethod($dispatch['method']);
break;
case 'function':
// 执行闭包
$data = self::invokeFunction($dispatch['function']);
break;
case 'response':
$data = $dispatch['response'];
break;
default:
throw new InvalidArgumentException('dispatch type not support');
}
} catch (HttpResponseException $exception) {
$data = $exception->getResponse();
}

。。。。。。
}

>>应用启动的应用调度
>>首先 检查语言配置
>>然后 路由解析获取调度信息
>>最后 根据调度类型执行不同类型应用

## 4-3 数据输出(App.php->run())


App.php;

public static function run(Request $request = null)

// 清空类的实例化
Loader::clearInstance();

// 输出数据到客户端
if ($data instanceof Response) {
$response = $data;
} elseif (!is_null($data)) {
// 默认自动识别响应输出类型
$isAjax = $request->isAjax();
$type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
$response = Response::create($data, $type);
} else {
$response = Response::create();
}

// 监听app_end
Hook::listen('app_end', $response);

return $response;
。。。。。。
}

>>应用逻辑执行完后,
>>首先 清空应用执行过程创建的对象
>>然后 根据应用执行后返回的数据创建响应对象(Response)
>>最后 调用相应对象的send()输出数据到客户端(start.php文件中)


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/213732.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号