Entry file index.php:
// 定义应用目录define(‘APP_PATH‘, __DIR__ . ‘/../application/‘);// 加载框架引导文件require __DIR__ . ‘/../thinkphp/start.php‘;
Boot file start.php:
namespace think;// 加载基础文件require __DIR__ . ‘/base.php‘;// 执行应用App::run()->send();
Base file base.php:
defined(‘THINK_PATH‘) or define(‘THINK_PATH‘, __DIR__ . DS);define(‘LIB_PATH‘, THINK_PATH . ‘library‘ . DS);define(‘CORE_PATH‘, LIB_PATH . ‘think‘ . DS);// 此处省略一堆的define...// 载入Loader类require CORE_PATH . ‘Loader.php‘;// 注册自动加载\think\Loader::register();
Think\app::run:
public static function run(Request $request = null){is_null($request) && $request = Request::instance();$config = self::initCommon();// 获取应用调度信息$dispatch = self::routeCheck($request, $config);// 记录当前调度信息$request->dispatch($dispatch);// 执行调度$data = self::exec($dispatch, $config);// 输出数据到客户端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();}return $response;}
Routecheck get $_server[' path_info '] get controller and operation name, return format:
array(2) { ["type"] => string(6) "module" ["module"] => array(3) { [0] => NULL [1] => string(5) "index" [2] => string(5) "hello" }}
The exec () call module () instantiates the controller and executes the action by reflection:
protected static function exec ($dispatch, $config) {$data = Self::module ($dispatch [' module '], $config); return $data;} /** * Execute module * @access public * @param array $result module/controller/operation * @param array $config configuration parameters * @param BOOL $convert Whether the controller is automatically converted and operation name * @return Mixed */public static function module ($result, $config) {//Get controller name $controller = Strip_tags ($result [1]?: $co nfig[' Default_controller ');//get operation name $action = Strip_tags ($result [2]?: $config [' default_action ']);//Instantiate Controller $instance = Self::invokeclass ($controller);//Execute Controller method return Self::invokemethod ([$instance, $action]);} /** * Invoke reflection Execution Class instantiation support Dependency Injection * @access public * @param string $class class name * @param array $vars variable * @return mixed */PUBL IC static function Invokeclass ($class, $vars = []) {$reflect = new \reflectionclass ($class); $constructor = $reflect-> ; GetConstructor (); if ($constructor) {$args = Self::bindparams ($constructor, $vars);} else {$args = [];} Return $reflect->newinstanceargs ($args);} /** * Methods that call reflection execution classes support parameter bindings * @access public * @param string|array $method method * @param array $vars variable * @return mixed */public static function InvokeMethod ($ method, $vars = []) {if (Is_array ($method)) {$class = Is_object ($method [0])? $method [0]: Self::invokeclass ($method [0]); $reflect = new \reflectionmethod ($class, $method [1]);} else {//static method $reflect = new \reflectionmethod ($method);} $args = Self::bindparams ($reflect, $vars); return $reflect->invokeargs (isset ($class)? $class: null, $args);}
Finally run () Gets the response object, calling the Response->send () method to output the data
Conclusion
$_server[' Path_info '] Get module/controller/operation, instantiate controller by reflection and perform operation
Questions
Why not use AutoLoad directly to dispatch the controller?
Disadvantages
does not support single module and multi-module coexistence, configuration files need to specify whether multiple modules, I think can be made coexistence, it is easy to implement the controller reuse, such as
- application/controller/index.php
- application/a/controller/index.php
When the URL is:/a/index/index, first execute the index method of the A module application/a/controller/index, if the A module does not exist this method, call the peripheral application/controller/ Index method under Index
THINKPHP5 Source Resolution (2) controller