app中php,附:(App.php)应用启动

[TOC]

* * * * *

## 1 本节是应用启动文件(/thinkphp/library/think/App.php)的其他静态方法分析

**self::initModule()**

~~~

private static function initModule($module, $config)

{

$module = (COMMON_MODULE == $module || !APP_MULTI_MODULE) ? '' : $module . DS;

if (is_file(APP_PATH . $module . 'init' . EXT)) {

include APP_PATH . $module . 'init' . EXT;

} else {

$path = APP_PATH . $module;

$config = Config::load(APP_PATH . $module . 'config' . EXT);

if ($config['app_status']) {

$config = Config::load(APP_PATH . $module . $config['app_status'] . EXT);

}

if ($config['extra_config_list']) {

foreach ($config['extra_config_list'] as $name => $file) {

$file = strpos($file, '.') ? $file : $path . $file . EXT;

Config::load($file, is_string($name) ? $name : pathinfo($file, PATHINFO_FILENAME));

}

}

if (is_file($path . 'alias' . EXT)) {

Loader::addMap(include $path . 'alias' . EXT);

}

if (APP_HOOK && is_file($path . 'tags' . EXT)) {

Hook::import(include $path . 'tags' . EXT);

}

if (is_file($path . 'common' . EXT)) {

include $path . 'common' . EXT;

}

if ($config['lang_switch_on'] && $module) {

Lang::load($path . 'lang' . DS . LANG_SET . EXT);

}

}

}

~~~

**self::initModule()源码分析**

`$module = (COMMON_MODULE == $module || !APP_MULTI_MODULE) ? '' : $module . DS;`

模块目录名称获取

~~~

if (is_file(APP_PATH . $module . 'init' . EXT)) {

include APP_PATH . $module . 'init' . EXT;

}

~~~

检查是否存在模块对应的初始化入口文件init.php,见使用范例 模块开发

~~~

$path = APP_PATH . $module;

$config = Config::load(APP_PATH . $module . 'config' . EXT);

~~~

加载模块的配置文件 见使用范例 模块开发

~~~

if ($config['app_status']) {

$config = Config::load(APP_PATH . $module . $config['app_status'] . EXT);

}

~~~

加载模块状态配置文件 见使用范例 模块开发

~~~

if ($config['extra_config_list']) {

foreach ($config['extra_config_list'] as $name => $file) {

$file = strpos($file, '.') ? $file : $path . $file . EXT;

Config::load($file, is_string($name) ? $name : pathinfo($file, PATHINFO_FILENAME));

}

}

~~~

加载模块扩展配置文件 见使用范例模块开发

~~~

if (is_file($path . 'alias' . EXT)) {

Loader::addMap(include $path . 'alias' . EXT);

}

~~~

加载模块别名配置文件 见使用范例模块开发

~~~

if (APP_HOOK && is_file($path . 'tags' . EXT)) {

Hook::import(include $path . 'tags' . EXT);

}

~~~

加载模块行为扩展文件 见使用范例模块开发

~~~

if (is_file($path . 'common' . EXT)) {

include $path . 'common' . EXT;

}

~~~

加载模块公共函数文件 见使用范例模块开发

~~~

if ($config['lang_switch_on'] && $module) {

Lang::load($path . 'lang' . DS . LANG_SET . EXT);

}

~~~

加载模块语言包文件 见使用范例模块开发

* * * * *

* * * * *

**2 self::parsePathinfo()源代码**

~~~

private static function parsePathinfo(array $config)

{

if (isset($_GET[$config['var_pathinfo']])) {

$_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']];

unset($_GET[$config['var_pathinfo']]);

} elseif (IS_CLI) {

// CLI模式下 index.php module/controller/action/params/...

$_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';

}

APP_HOOK && Hook::listen('path_info');

if (!isset($_SERVER['PATH_INFO'])) {

foreach ($config['pathinfo_fetch'] as $type) {

if (!empty($_SERVER[$type])) {

$_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?

substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];

break;

}

}

}

}

~~~

**self::parsePathinfo()源代码分析**

~~~

if (isset($_GET[$config['var_pathinfo']])) {

$_SERVER['PATH_INFO'] = $_GET[$config['var_pathinfo']];

unset($_GET[$config['var_pathinfo']]);

} elseif (IS_CLI) {

// CLI模式下 index.php module/controller/action/params/...

$_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';

}

~~~

检查$_GET参数是否包含$config配置的兼容模式参数,

兼容模式参数见附:全局配置文件

如果有 设置$_SERVER['PATH_INFO']为$_GET中兼容模式参数对应的参数的值

并删除$_GET兼容模式参数

如果没有检查模式检查

检查是否是CLI模式 然后设置$_SERVER['PATH_INFO']为CLI的$_SERVER['argv'][1]参数

这里的PATH_INFO其实就是调用的文件名称与参数

` APP_HOOK && Hook::listen('path_info');`

path_info分析回调

~~~

if (!isset($_SERVER['PATH_INFO'])) {

foreach ($config['pathinfo_fetch'] as $type) {

if (!empty($_SERVER[$type])) {

$_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?

substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];

break;

}

}

}

~~~

如果上面获取PATH_INFO失败

那么从配置信息$config['pathinfp_fetch']中依次读取PATH_INFP信息

经过上面调用获取了全局变量$_SERVER['PATH_INFO']的值,这个值在下面的self::route()中会用到

* * * * *

* * * * *

**3 self::route()源代码**

~~~

public static function route(array $config)

{

self::parsePathinfo($config);

if (empty($_SERVER['PATH_INFO'])) {

$_SERVER['PATH_INFO'] = '';

define('__INFO__', '');

define('__EXT__', '');

} else {

$_SERVER['PATH_INFO'] = trim($_SERVER['PATH_INFO'], '/');

define('__INFO__', $_SERVER['PATH_INFO']);

define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION)));

if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) {

throw new Exception('url suffix deny');

}

$_SERVER['PATH_INFO'] = preg_replace($config['url_html_suffix'] ? '/\.(' . trim($config['url_html_suffix'], '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', __INFO__);

}

$depr = $config['pathinfo_depr'];

$result = false;

if (APP_ROUTE_ON && !empty($config['url_route_on'])) {

if (!empty($config['route'])) {

Route::register($config['route']);

}

$result = Route::check($_SERVER['PATH_INFO'], $depr, !IS_CLI ? $config['url_domain_deploy'] : false);

if (APP_ROUTE_MUST && false === $result && $config['url_route_must']) {

throw new Exception('route not define ');

}

}

if (false === $result) {

$result = Route::parseUrl($_SERVER['PATH_INFO'], $depr);

}

self::dispatch($result);

}

~~~

**self::route()源代码分析**

`self::parsePathinfo($config);`

调用上面的self::parsePathinfo()获取$_SERVER['PATH_INFO']的值

~~~

$_SERVER['PATH_INFO'] = '';

define('__INFO__', '');

define('__EXT__', '');

~~~

如果$_SERVER['PATH_INFO']为空

设置`__INFO__ __EXT__`全局变量为空

~~~

$_SERVER['PATH_INFO'] = trim($_SERVER['PATH_INFO'], '/');

define('__INFO__', $_SERVER['PATH_INFO']);

define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION)));

if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) {

throw new Exception('url suffix deny');

}

$_SERVER['PATH_INFO'] = preg_replace($config['url_html_suffix'] ? '/\.(' . trim($config['url_html_suffix'], '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', __INFO__);

~~~

如果$_SERVER['PATH_INFO']为空

设置`__INFO__ __EXT__`为$_SERVER['PATH_INFO']的相应值。

并检查是否禁用相应的后缀请求 见使用范例 禁用URL后缀

接着去除正常的Url后缀???待分析

`$depr = $config['pathinfo_depr'];`

获取配置的pathinfo_depr,

~~~

if (APP_ROUTE_ON && !empty($config['url_route_on'])) {

}

~~~

检查全局变量APP_ROUTE_ON 是否开启路由检测

全局变量设置见 [附:全局变量文件](http://www.kancloud.cn/zmwtp/tp5/119430)

如果开启

~~~

if (!empty($config['route'])) {

Route::register($config['route']);

}

~~~

将配置中的路由添加到全局路由定义

全局路由定义见 [附:全局路由文件](http://www.kancloud.cn/zmwtp/tp5/119438)

`$result = Route::check($_SERVER['PATH_INFO'], $depr, !IS_CLI ? $config['url_domain_deploy'] : false);`

检查路由 ???待分析

~~~

if (APP_ROUTE_MUST && false === $result && $config['url_route_must']) {

throw new Exception('route not define ');

}

~~~

路由检测结果分析

~~~

if (false === $result) {

$result = Route::parseUrl($_SERVER['PATH_INFO'], $depr);

}

~~~

路由url分析 见 [附:全局路由文件](http://www.kancloud.cn/zmwtp/tp5/119438)

`self::dispatch($result);`

注册路由分析结果到app调度类型$dispatch

调度类型的使用见 [应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428)

## 3 总结

**initModule() 模块的初始化实现**

在系统主流程App::run()中有两处调用,

一处是App::run()刚开始总的公共模块初始化

self::initModule(COMMON_MODULE,Config::get())

一处是App::module()中的应用模块初始化

self::initModule(MODULE_NAME, $config);

**parsePathinfo() 获取请求信息**

**route() 根据请求信息进行路由分派**

其他的函数包括

run() 应用启动流程 见 [应用启动文件](http://www.kancloud.cn/zmwtp/tp5/119426)

invokeFunction() 调度回调函数 见 [应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428)

invokeMethod() 调度回调方法 见 [应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428)

bindParams() 调度参数合成 见 [应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428)

module() 调度回调模块 见 [应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428)

dispathc() 调度注册见[应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值