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

应用组织 - TP5源代码阅读

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

应用组织 - TP5源代码阅读



[TOC]

* * * * *
#1 应用入口(App.php->run())

>>在[应用启动](http://www.kancloud.cn/zmwtp/tp/210985)过程中,

>创建[请求对象](http://www.kancloud.cn/zmwtp/tp/210989)后,根据注册的[路由规则](http://www.kancloud.cn/zmwtp/tp/210990),解析请求对象为相应的应用类型

>根据不同的应用类型执行不同的应用

>其中包括六种类型

>redirect,module,controller,method,function,response.

App.php->run();

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');
}


#2 应用类型

## 2-1 redirect类型

### redirect应用调度


case 'redirect':
// 执行重定向跳转
$data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);

>>redircet类型 使用Response创建重定向跳转,跳转到指定Url运行应用。

### redirect应用处理
>>redirect应用,创建redirect类响应对象,跳转到指定url。redirect类响应对象 见 [网络响应](http://www.kancloud.cn/zmwtp/tp/210995) 章节


## 2-2 module类型

### module应用调度


case 'module':
// 模块/控制器/操作
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);

>>module类型 调用App::moudle()执行特定模块的应用

### module应用处理

public static function module($result, $config, $convert = null)
{
if (is_string($result)) {
$result = explode('/', $result);
}
$request = Request::instance();
if ($config['app_multi_module']) {
// 多模块部署
$module = strip_tags(strtolower($result[0] ?: $config['default_module']));
$bind = Route::getBind('module');
$available = false;
if ($bind) {
// 绑定模块
list($bindModule) = explode('/', $bind);
if (empty($result[0])) {
$module = $bindModule;
$available = true;
} elseif ($module == $bindModule) {
$available = true;
}
} elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) {
$available = true;
}

// 模块初始化
if ($module && $available) {
// 初始化模块
$request->module($module);
$config = self::init($module);
} else {
throw new HttpException(404, 'module not exists:' . $module);
}
} else {
// 单一模块部署
$module = '';
$request->module($module);
}
// 当前模块路径
App::$modulePath = APP_PATH . ($module ? $module . DS : '');

// 是否自动转换控制器和操作名
$convert = is_bool($convert) ? $convert : $config['url_convert'];
// 获取控制器名
$controller = strip_tags($result[1] ?: $config['default_controller']);
$controller = $convert ? strtolower($controller) : $controller;

// 获取操作名
$actionName = strip_tags($result[2] ?: $config['default_action']);
$actionName = $convert ? strtolower($actionName) : $actionName;

// 设置当前请求的控制器、操作
$request->controller(Loader::parseName($controller, 1))->action($actionName);

// 监听module_init
Hook::listen('module_init', $request);

try {
$instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);
if (is_null($instance)) {
throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1));
}
// 获取当前操作名
$action = $actionName . $config['action_suffix'];
if (!preg_match('/^[A-Za-z](w)*$/', $action)) {
// 非法操作
throw new ReflectionException('illegal action name:' . $actionName);
}

// 执行操作方法
$call = [$instance, $action];
Hook::listen('action_begin', $call);

$data = self::invokeMethod($call);
} catch (ReflectionException $e) {
// 操作不存在
if (method_exists($instance, '_empty')) {
$reflect = new ReflectionMethod($instance, '_empty');
$data = $reflect->invokeArgs($instance, [$action]);
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
} else {
throw new HttpException(404, 'method not exists:' . (new ReflectionClass($instance))->getName() . '->' . $action);
}
}
return $data;
}

>>初始化请求的模块,然后查找控制器名,操作名
>使用App::invokeMethod()调用其请求的控制器的操作

## 2-3 controller类型

### controller应用调度

case 'controller':
// 执行控制器操作
$data = Loader::action($dispatch['controller']);

>>controller类型 调用Loader执行特定应用控制器

### controller应用处理
>>调用Loader的操作实例化,远程调用控制器的操作

## 2-4 method类型

### method应用调度

case 'method':
// 执行回调方法
$data = self::invokeMethod($dispatch['method']);

>>method类型 调用App::invokeMethod()执行特定应用的方法

### method应用处理

public static function invokeMethod($method, $vars = [])
{
if (is_array($method)) {
$class = is_object($method[0]) ? $method[0] : new $method[0](Request::instance());
$reflect = new ReflectionMethod($class, $method[1]);
} else {
// 静态方法
$reflect = new ReflectionMethod($method);
}
$args = self::bindParams($reflect, $vars);
// 记录执行信息
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
}

>>使用反射执行请求的控制器的操作

## 2-5 function类型
### function应用调度

case 'function':
// 执行闭包
$data = self::invokeFunction($dispatch['function']);

>>function类型 调用App::invokeFunction()执行特定应用闭包

### function应用处理

public static function invokeFunction($function, $vars = [])
{
$reflect = new ReflectionFunction($function);
$args = self::bindParams($reflect, $vars);
// 记录执行信息
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
return $reflect->invokeArgs($args);
}

>>使用反射执行函数或闭包。


## 2-6 response类型

case 'response':
$data = $dispatch['response'];

>>response类型 直接保存调度的response信息到输出数据


#3 应用类型总结

## 3-1 类型的特征

>>根据不同类型的复杂度从低到高依次为

>1 response类型
>2 function类型
>3 method类型
>4 controller类型
>5 module类型
>6 redirect类型

>>根据类型的使用频率从高到低依次为

>1 redirect类型
>2 module类型
>3 controller类型
>4 method类型
>5 function类型
>6 response类型
>也就是说大多数应用类型为redirect和module类型。

>>不同类型的应用可以表示为不同形式的应用地址

>应用地址在Url路由的路由注册中使用。

## 3-2 类型的检测

>>类型的获取使用App::routeCheck()获取请求的应用类型

>应用类型的获取在[网络请求](http://www.kancloud.cn/zmwtp/tp/210989)的[Url路由](http://www.kancloud.cn/zmwtp/tp/210990)的路由检测中获取


App.php;

public static function routeCheck($request, array $config)
{
$path = $request->path();
$depr = $config['pathinfo_depr'];
$result = false;
// 路由检测
$check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
if ($check) {
// 开启路由
if (is_file(RUNTIME_PATH . 'route.php')) {
// 读取路由缓存
$rules = include RUNTIME_PATH . 'route.php';
if (is_array($rules)) {
Route::rules($rules);
}
} else {
$files = $config['route_config_file'];
foreach ($files as $file) {
if (is_file(CONF_PATH . $file . CONF_EXT)) {
// 导入路由配置
$rules = include CONF_PATH . $file . CONF_EXT;
if (is_array($rules)) {
Route::import($rules);
}
}
}
}

// 路由检测(根据路由定义返回不同的URL调度)
$result = Route::check($request, $path, $depr, $config['url_domain_deploy']);
$must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];
if ($must && false === $result) {
// 路由无效
throw new HttpException(404, 'Route Not Found');
}
}
if (false === $result) {
// 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
}
return $result;
}




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

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

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