<?php
/*设置脚本开始时间 define('LARAVEL_START', microtime(true));
引入composer的自动加载,在composer.json中可以看出相当于
require('app/*') require('database/*') require('vendor/*')
之后使用时只要引入命名空间即可
*/
require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
/*在phpstrom中ctrl+左键单击查看app.php代码。*/
/*app.php代码如下:*/
/*首先创建app服务容器,即ioc容器,稍后分析*/
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
/*
看官方文档可知,
singleton 方法绑定一个只需要解析一次的类或接口到容器,然后接下来对容器的调用将会返回同一个实例
即以后需要使用Illuminate\Contracts\Http\Kernel这个类时,会返回App\Http\Kernel
使用代码 $app->make('Illuminate\Contracts\Http\Kernel')
*/
/*
在laravel中Contracts(契约)文件夹里面的都是interfere类
实现时都在Foundation这个文件夹中
而查看App\Http\Kernel会发现它继承了实现接口类的类
*/
/*
这里绑定的是http启动的一些启动服务(session。env。config等)和中间件。以后分析。
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
/*
这里绑定的是控制台用的服务,即php artisan
如果上线了可以省去。
*/
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
/*
绑定错误提示类
上线后可以省去。
*/
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
return $app;
/*继续查看index.php*/
/*
这里解析http的核心
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
/*
处理请求,生成响应
这里的handle函数是一大难点。其实现贼复杂
*/
$response = $kernel->handle(
/*
这里利用symfont的http request解析http请求
里面有post。get。文件。路径等很多信息。
*/
$request = Illuminate\Http\Request::capture()
);
/*发送响应*/
$response->send();
/*后续处理,比如写log等*/
$kernel->terminate($request, $response);
/*由app.php里面的singleton很容易得知handle函数的所在*/
public function handle($request)
{
try {
/*这是symfont的允许在路由中使用GET和POST以外的HTTP方法 */
$request->enableHttpMethodParameterOverride();
/*把request交给router处理,首先肯定是要匹配的你在route里面定义的方法*/
$response = $this->sendRequestThroughRouter($request);
} catch (Exception $e) {
/*接下来都是些错误处理*/
$this->reportException($e);
$response = $this->renderException($request, $e);
} catch (Throwable $e) {
$this->reportException($e = new FatalThrowableError($e));
$response = $this->renderException($request, $e);
}
/*分发事件,让事件监听获取信息,以后说*/
event(new Events\RequestHandled($request, $response));
return $response;
}
/*然后我们专注于sendRequestThroughRouter这函数*/
protected function sendRequestThroughRouter($request)
{
/*
绑定一个实例。
laravel实现3种绑定,bind singleton instance。每次绑定如果名字相同会覆盖掉上次绑定的。
bind每次make返回的都是新的实例
singleton每次make返回的都是同一个实例
instance每次返回的都是绑定时给的实例
*/
$this->app->instance('request', $request);
/*未知作用*/
Facade::clearResolvedInstance('request');
/*启动初始服务,比如config。env等,以后有机会分析*/
$this->bootstrap();
/*利用管道类处理请求,先绑定app容器,然后发送request请求,通过中间件,最后匹配路由,并执行route里面定义的方法,生成并返回reponse,其中源码绕来绕去就不一一解析*/
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}