ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
请求流程 在应用初始化结束之后,框架运行所具备的基本功能就加载结束了。然后就应该是处理用户请求了。首先我们应该看的就是流程。 if (is_file($this->app->getBasePath() . 'middleware.php')) { $this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php'); } if ($this->multi) { $this->parseMultiApp(); } $this->app->event->withEvent($this->app->config->get('app.with_event', true)); $this->app->event->trigger('HttpRun'); $withRoute = $this->app->config->get('app.with_route', true) ? function () { $this->loadRoutes(); } : null; return $this->app->route->dispatch($request, $withRoute); 加载全局中间件 app/middleware.php, 默认这些都是关闭的 多应用处理 设置事件监听并且监听 httpRun 事件 加载路由,有一个需要注意的就是框架支持注解路由。默认关闭 分发请求 ## **请求流程** 对于一个HTTP应用来说,从用户发起请求到响应输出结束,大致的标准请求流程如下: * 访问入口文件index.php 同时 载入`Composer`的自动加载`autoload`文件 * 入口文件实例化系统应用基础类`think\App` * * **1、$http=new think\App->http;** * **2、$response=$http->run();** * ① $this->runWithRequest($request) #将请求信息对象传入 * $this->initialize() * $this->app->initialize(); * 加载全局中间件(app/middleware.php) * 解析多应用 $this->parseMultiApp() * 设置开启事件机制 * 监听HttpRun ($this->app->event->trigger('HttpRun');) * app.with_route为true则闭包函数加载路由配置文件($this->loadRoutes();) * $routePath = $this->getRoutePath();确定加载路径 如:"D:\phpStudy\WWW\tp6\route\admin\" * $files = glob($routePath . '*.php'); //加载routePath所有的.php后缀的路由配置文件 $files = glob($routePath . '*.php'); * 触发 监听 RouteLoaded事件 * return $this->app->route->dispatch($request, $withRoute);//路由调度参数:$withRoute为包含加载路由文件的比好函数或者null; $withRoute();执行此闭包函数 * return $this->check();//检测URL路由 * ... * ② return $response->setCookie($this->app->cookie); * **3、$response->send()** * **4、$http->end($response);** * 获取应用目录等相关路径信息 * 加载全局的服务提供`provider.php`文件 * 设置容器实例及应用对象实例,确保当前容器对象唯一 * 从容器中获取`HTTP`应用类`think\Http` * 执行`HTTP`应用类的`run`方法启动一个`HTTP`应用 * 获取当前请求对象实例(默认为`app\Request`继承`think\Request`)保存到容器 * 执行`think\App`类的初始化方法`initialize` * 加载环境变量文件`.env`和全局初始化文件 * 加载全局公共文件、系统助手函数、全局配置文件、全局事件定义和全局服务定义 * 判断应用模式(调试或者部署模式) * 监听`AppInit`事件 * 注册异常处理 * 服务注册 * 启动注册的服务 * 加载全局中间件定义 * 如果是多应用模式则解析当前实际访问的应用名 * 自动多应用识别,检查域名绑定应用和应用映射及禁止访问列表 * 加载应用公共文件、应用配置文件、应用事件定义、应用中间件定义和应用服务提供定义 * 设置当前应用的命名空间 * 监听`HttpRun`事件 * 执行路由调度(`Route`类`dispatch`方法) * 如果开启路由则检查路由缓存 * 加载路由定义 * 如果开启注解路由则检测注解路由 * 路由检测(中间流程很复杂 略) * 路由调度对象`think\route\Dispatch`初始化 * 设置当前请求的控制器和操作名 * 注册路由中间件 * 绑定数据模型 * 设置路由额外参数 * 执行数据自动验证 * 执行路由调度子类的`exec`方法返回响应`think\Response`对象 * 获取当前请求的控制器对象实例 * 利用反射机制注册控制器中间件 * 执行控制器方法以及前后置中间件 * 执行当前响应对象的`send`方法输出 * 执行HTTP应用对象的`end`方法善后 * 监听`HttpEnd`事件 * 写入当前请求的日志信息 * 本地化当前请求的会话数据 至此,当前请求流程结束。 * 载入`Composer`的自动加载`autoload`文件【index.php】 * 实例化系统应用基础类`think\App`【index.php】 * 获取应用目录等相关路径信息【App.php<==>APP::__construct】 * 加载全局的服务提供`provider.php`文件【App.php<==>APP::__construct】 * 设置容器实例及应用对象实例,确保当前容器对象唯一【App.php<==>APP::__construct】 * 从容器中获取`HTTP`应用类`think\Http`【index.php】 * 执行`HTTP`应用类的`run`方法启动一个`HTTP`应用【index.php】 * 获取当前请求对象实例(默认为`app\Request`继承`think\Request`)保存到容器【vendor\topthink\framework\src\think\Http.php《==》Http::run】 * 执行`think\App`类的初始化方法`initialize`【Http::runWithRequest】 * 加载环境变量文件`.env`和全局初始化文件【App::initialize】 * ~~加载全局公共文件、系统助手函数、全局配置文件、全局事件定义和全局服务定义~~【App::initialize】 * 判断应用模式(在App::debugModeInit读取并根据配置文件启用调试或者部署模式)【App::initialize】 * 加载全局初始化文件(common.php/helper.php/所有配置文件/event.php/service.php) * 加载应用默认语言包 * 监听`AppInit`事件【App::initialize】 * 应用初始化器遍历initializers属性并实例化下面三个类 * 注册异常处理【Error:init】vendor\\topthink\\framework\\src\\think\\initializer\\Error.php * 服务注册【RegisterService:;init】vendor\\topthink\\framework\\src\\think\\initializer\\RegisterService.php * vendor\\topthink\\framework\\src\\think\\service\\PaginatorService.php * vendor\\topthink\\framework\\src\\think\\Service.php * vendor\\topthink\\framework\\src\\think\\service\\ValidateService.php * vendor\\topthink\\framework\\src\\think\\service\\ValidateService.php * 启动注册的服务【BootService::init】endor\\topthink\\framework\\src\\think\\initializer\\BootService.php * 加载全局中间件定义【Http::runWithRequest】 * 开启事件机制【Http::runWithRequest】 * 监听`HttpRun`事件【Http::runWithRequest】 * 执行全局中间件【Http::runWithRequest】 * 执行路由调度(主要是调用`Route`类`dispatch`方法)【Http::dispatchToRoute】 * 如果app.with_route配置开启路由 则检查路由缓存【Route::dispatchToRoute】 * 执行Http::loadRoutes方法加载路由定义【Route::dispatchToRoute】 * 监听`RouteLoaded`事件【Route::loadRoutes】 * 初始化默认域名【Route::__construct】 * 读取路由映射文件【Route::__construct】 * 如果开启注解路由则检测注解路由(route_annotation配置)??? * Route::check路由检测(中间流程很复杂 略)【Route::dispatch】 * $dispatch->run() 路由调度对象`think\route\Dispatch`初始化【Route::dispatch】 * 设置当前请求的控制器和操作名 * 注册路由中间件【Route::init】 * 绑定数据模型 * 设置路由额外参数 * 执行数据自动验证 * 执行路由调度子类的`exec`方法返回响应`think\Response`对象【Dispatch::run】 * 获取当前请求的控制器对象实例`vendor\topthink\framework\src\think\route\dispatch\Controller.php下的Controller::exe()` * 利用反射机制注册控制器中间件`同上:Controller::exe()` * 执行控制器方法以及前后置中间件`同上:Controller::exe()` * 执行当前响应对象的`send`方法输出【index.php】 * 执行HTTP应用对象的`end`方法善后【index.php】 * 监听`HttpEnd`事件 * 执行中间件的`end`回调 * 写入当前请求的日志信息