02
08月
2020
执行流程
// 执行应用并响应
Container::get('app')->run()->send();thinkphp/library/think/App.php
/**
* 执行应用程序
* @access public
* @return Response
* @throws Exception
*/
public function run()
{
try {
......
$dispatch = $this->dispatch;
if (empty($dispatch)) {
// 路由检测
$dispatch = $this->routeCheck()->init();
}
// 记录当前调度信息
$this->request->dispatch($dispatch);
......
} catch (HttpResponseException $exception) {
......
}
$this->middleware->add(function (Request $request, $next) use ($dispatch, $data) {
return is_null($data) ? $dispatch->run() : $data;
});
......
}$dispatch 获取控制器和操作名,执行路由调度
thinkphp/library/think/route/Dispatch.php
/**
* 执行路由调度
* @access public
* @return mixed
*/
public function run()
{
......
$data = $this->exec();
......
}exec() 通过反射实例化控制器和执行方法
thinkphp/library/think/route/dispatch/Module.php
public function exec()
{
// 监听module_init
$this->app['hook']->listen('module_init');
try {
// 实例化控制器
$instance = $this->app->controller($this->controller,
$this->rule->getConfig('url_controller_layer'),
$this->rule->getConfig('controller_suffix'),
$this->rule->getConfig('empty_controller'));
} catch (ClassNotFoundException $e) {
throw new HttpException(404, 'controller not exists:' . $e->getClass());
}
$this->app['middleware']->controller(function (Request $request, $next) use ($instance) {
// 获取当前操作名
$action = $this->actionName . $this->rule->getConfig('action_suffix');
// 检查实例中是否可以执行方法
if (is_callable([$instance, $action])) {
// 执行操作方法
$call = [$instance, $action];
// 严格获取当前操作方法名
$reflect = new ReflectionMethod($instance, $action);
$methodName = $reflect->getName();
$suffix = $this->rule->getConfig('action_suffix');
$actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;
$this->request->setAction($actionName);
// 自动获取请求变量
$vars = $this->rule->getConfig('url_param_type')
? $this->request->route()
: $this->request->param();
$vars = array_merge($vars, $this->param);
} elseif (is_callable([$instance, '_empty'])) {
// 空操作
$call = [$instance, '_empty'];
$vars = [$this->actionName];
$reflect = new ReflectionMethod($instance, '_empty');
} else {
// 操作不存在
throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
}
$this->app['hook']->listen('action_begin', $call);
$data = $this->app->invokeReflectMethod($instance, $reflect, $vars);
return $this->autoResponse($data);
});
return $this->app['middleware']->dispatch($this->request, 'controller');
}最终获得Response对象,调用send()方法输出数据
thinkphp/library/think/Response.php
/**
* 发送数据到客户端
* @access public
* @return void
* @throws \InvalidArgumentException
*/
public function send()
{
// 监听response_send
$this->app['hook']->listen('response_send', $this);
// 处理输出数据
$data = $this->getContent();
// Trace调试注入
if ('cli' != PHP_SAPI && $this->app['env']->get('app_trace', $this->app->config('app.app_trace'))) {
$this->app['debug']->inject($this, $data);
}
if (200 == $this->code && $this->allowCache) {
$cache = $this->app['request']->getCache();
if ($cache) {
$this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate';
$this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
$this->header['Expires'] = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT';
$this->app['cache']->tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]);
}
}
if (!headers_sent() && !empty($this->header)) {
// 发送状态码
http_response_code($this->code);
// 发送头部信息
foreach ($this->header as $name => $val) {
header($name . (!is_null($val) ? ':' . $val : ''));
}
}
$this->sendData($data);
if (function_exists('fastcgi_finish_request')) {
// 提高页面响应
fastcgi_finish_request();
}
// 监听response_end
$this->app['hook']->listen('response_end', $this);
// 清空当次请求有效的数据
if (!($this instanceof RedirectResponse)) {
$this->app['session']->flush();
}
}