[TOC] * * * * * ## 1 应用启动源代码(/thinkphp/library/think/App的run()) 注:App.php其他部分源代码分析见[附:应用启动文件](http://www.kancloud.cn/zmwtp/tp5/119429) ~~~ class App { public static function run() { self::initModule(COMMON_MODULE, Config::get()); $config = Config::get(); if (!empty($config['root_namespace'])) { Loader::addNamespace($config['root_namespace']); } if (!empty($config['extra_file_list'])) { foreach ($config['extra_file_list'] as $file) { $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; if (is_file($file)) { include_once $file; } } } date_default_timezone_set($config['default_timezone']); APP_HOOK && Hook::listen('app_init'); if ($config['lang_switch_on']) { defined('LANG_SET') or define('LANG_SET', Lang::range()); Lang::load(THINK_PATH . 'lang' . DS . LANG_SET . EXT); if (!APP_MULTI_MODULE) { Lang::load(APP_PATH . 'lang' . DS . LANG_SET . EXT); } } if (empty(self::$dispatch['type'])) { self::route($config); } APP_DEBUG && Log::record('[ ROUTE ] ' . var_export(self::$dispatch, true), 'info'); APP_HOOK && Hook::listen('app_begin'); switch (self::$dispatch['type']) { case 'redirect': header('Location: ' . self::$dispatch['url'], true, self::$dispatch['status']); break; case 'module': $data = self::module(self::$dispatch['module'], $config); break; case 'controller': $data = Loader::action(self::$dispatch['controller'], self::$dispatch['params']); break; case 'method': $data = self::invokeMethod(self::$dispatch['method'], self::$dispatch['params']); break; case 'function': $data = self::invokeFunction(self::$dispatch['function'], self::$dispatch['params']); break; default: throw new Exception('dispatch type not support', 10008); } APP_HOOK && Hook::listen('app_end', $data); return Response::send($data, Response::type(), Config::get('response_return')); } } ~~~ ## 2 应用启动App::run()源代码分析 ### 1 应用初始化 ~~~ self::initModule(COMMON_MODULE,Config::get()) ~~~ >[info] 应用的模块初始化 具体的实现见框架流程的[附:应用启动文件](http://www.kancloud.cn/zmwtp/tp5/119429) ~~~ $config = Config::get() ~~~ >[info] 全局配置参数获取 **下面根据配置参数注册根命名空间,加载额外配置文件,设置系统时区** 具体实现见框架流程的[附:全局配置文件](http://www.kancloud.cn/zmwtp/tp5/119434) ~~~ if (!empty($config['root_namespace'])) { Loader::addNamespace($config['root_namespace']); } ~~~ >[info] 注册根命名空间 具体实现见框架流程的[附:自动加载器](http://www.kancloud.cn/zmwtp/tp5/119431) ~~~ if (!empty($config['extra_file_list'])) { foreach ($config['extra_file_list'] as $file) { $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; if (is_file($file)) { include_once $file; } } } ~~~ >[info] 加载配置的额外文件 ~~~ date_default_timezone_set($config['default_timezone']); ~~~ >[info] 设置系统时区 系统时区见基础原理的[php系统时区](http://www.kancloud.cn/zmwtp/tp5/119448) ~~~ APP_HOOK && Hook::listen('app_init'); ~~~ >[info] 应用初始化回调处理 监听回调见框架流程的[附:监听回调注册文件](http://www.kancloud.cn/zmwtp/tp5/119435) ### 2 Url路由解析,并设置调度类型 ~~~ if (empty(self::$dispatch['type'])) { self::route($config); } ~~~ >[info] 解析url 调用self::route(),解析url,生成$dispatch。 路由分析见框架流程的[附:全局路由文件](http://www.kancloud.cn/zmwtp/tp5/119438) ~~~ APP_DEBUG && Log::record('[ ROUTE ] ' . var_export(self::$dispatch, true), 'info'); ~~~ >[info] 日志记录路由分析信息 日志记录的实现见框架流程的[附:日志记录文件](http://www.kancloud.cn/zmwtp/tp5/119437) ~~~ APP_HOOK && Hook::listen('app_begin'); ~~~ >[info] 同上 应用启动回调处理 * * * * * ### 3 应用调度 ~~~ switch (self::$dispatch['type']) { case 'redirect': header('Location: ' . self::$dispatch['url'], true, self::$dispatch['status']); break; case 'module': $data = self::module(self::$dispatch['module'], $config); break; case 'controller': $data = Loader::action(self::$dispatch['controller'], self::$dispatch['params']); break; case 'method': $data = self::invokeMethod(self::$dispatch['method'], self::$dispatch['params']); break; case 'function': $data = self::invokeFunction(self::$dispatch['function'], self::$dispatch['params']); break; default: throw new Exception('dispatch type not support', 10008); } ~~~ 根据调度器类型self::$dispatch['type']进行不同的应用的调度。 将应用业务执行的结果保存到$data中 **应用的调度是应用启动的核心部分。** 其内容见框架流程的[应用调度分析](http://www.kancloud.cn/zmwtp/tp5/119428) ~~~ APP_HOOK && Hook::listen('app_end', $data); ~~~ 同上 应用完成回调处理 ### 4 输出数据到客户端 ~~~ return Response::send($data, Response::type(), Config::get('response_return')); ~~~ 调用Response::send()返回数据到客户端 输出的原理见框架流程的[附:数据输出文件,](http://www.kancloud.cn/zmwtp/tp5/119439) ## 3 总结 应用启动App::run()是框架核心。 首先 根据配置初始化应用的公共模块 然后 根据配置参数依次配注册根命名空间 加载额外文件 设置系统时区, 此时调用监听app_init事件的回调方法 然后 开启多语言机制 接着 对url进行路由分析,获取url可以使用的调度类型 最后 根据调度类型,分别调用应用的对应逻辑业务实现。 **这里的路由分析和应用调度是框架从框架底层到应用跳转的核心部分,** 因此单独拿出[一节](http://www.kancloud.cn/zmwtp/tp5/119428)来进行分析。 路由分析中涉及路由规则的定义,使用方法见使用范例的[路由规则注册](http://www.kancloud.cn/zmwtp/tp5/120040) 调度类型可以灵活定义业务应用的组织方式,使用方法见使用范例的 [多种应用组织](http://www.kancloud.cn/zmwtp/tp5/120210)