laravel生命周期
一,入口文件
index.php
bootstrap/autoload.php --> 自动加载
bootstrap/app.php --> 初始化服务容器(注册基础的服务提供者(事件、日志、路由)、注册核心类别名)
bootstrap/app.php --> 注册共享的Kernel和异常处理器
Foundation\Http\Kernel.php --> 处理请求和响应
index.php --> 将响应信息发送到浏览器
index.php --> 处理继承自TerminableMiddleware接口的中间件(Session)并结束应用生命周期
二,自动加载
1,包括全局函数的加载、顶级命名空间映射、PSR0、PSR4标准的实现
#核心加载类: $loader = new \Composer\Autoload\ClassLoader(); #核心查找方法: loadClass()->findFile() #PSR0的类和路径映射 autoload_namespaces.php #PSR4的类和路径映射 autoload_psr4.php #具体类和路径映射 autoload_classmap.php #其他自动加载的php文件 (一次性全部加载非自动) autoload_files.php
注意:命名空间本质上是一种规范:更加细致的管理类(使用namespace),选择类(使用use)和加载类(通过命名空间和路径的建立映射关系,动态加载)
三,服务容器
#核心类
$app = new Illuminate\Foundation\Application(path) #继承自Illuminate\Container\Container
#核心机制
1,反射
2,class_alias //核心类别名
构造方法中初始化(重点方法)
$this->registerBaseBindings();//绑定自身实例 #注册服务提供者,内部会绑定各种服务实现类 $this->registerBaseServiceProviders();//注册基础服务 //事件机制 $this->register(new EventServiceProvider($this)); //日志服务 $this->register(new LogServiceProvider($this)); //路由服务 $this->register(new RoutingServiceProvider($this)); $this->registerCoreContainerAliases();//别名机制可以使门面类对应到实例
实例对象注册了3个类
//http服务的核心类 $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 );
四,生命周期核心类:App\http\Kernel
#实例核心类:
$app->make(Illuminate\Contracts\Http\Kernel::class); #继承自Illuminate\Foundation\Http\Kernel
构造函数初始化
#绑定应用类 $this->app = $app; #绑定路由 $this->router = $router; #自带全局中间件 protected $middleware=[...] #设置路由中间件 //前置中间件 $router->middlewarePriority = $this->middlewarePriority; //中间件组 $router->middlewareGroup($key, $middleware); //中间件别名 $router->aliasMiddleware($key, $middleware);
handle()方法
#调用 $response = $kernel->handle( $request = Illuminate\Http\Request::capture() );
#具体逻辑 $this->app->instance('request', $request);//绑定resuqet实例到应用 Facade::clearResolvedInstance('request'); $this->bootstrap(); return (new Pipeline($this->app)) ->send($request)//处理请求 ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter());
bootstrap() 方法(重点方法)
#核心启动类 protected $bootstrappers = [ \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, #注册应用的环境变量 put_env();$_ENV=[];$_SERVER=[]; \Illuminate\Foundation\Bootstrap\LoadConfiguration::class, #绑定config实例new Config\Repository(),注册配置文件,设置了时区,编码,运行模式 \Illuminate\Foundation\Bootstrap\HandleExceptions::class, #错误异常的捕捉,会使用异常处理类$this->app->make(ExceptionHandler::class) \Illuminate\Foundation\Bootstrap\RegisterFacades::class, #注册门面类,调用Foundation\AliasLoader,最后使用class_alias(),此处有待深入 \Illuminate\Foundation\Bootstrap\RegisterProviders::class, #注册全部的服务提供者,服务提供者就是绑定各种服务实现类到应用实例$app \Illuminate\Foundation\Bootstrap\BootProviders::class, #服务提供者注册完成后的初始化 ]; #会依次调用启动类的bootstrap()方法
terminate()方法,执行完以后
$this->terminateMiddleware($request, $response);#所有中间件的terminate()方法 $this->app->terminate();#依次调用$this->terminatingCallbacks中的回调函数
五,处理请求和响应
其实是在Illuminate\Foundation\Http\Kernel中的handle方法中完成的
#核心代码1:全局中间件 return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter()); #调用Illuminate\Routing\Router的dispatchToRoute(Request $request)方法: $route = $this->findRoute($request); $request->setRouteResolver(function () use ($route) { return $route; }); $this->events->dispatch(new Events\RouteMatched($route,$request)); $response = $this->runRouteWithinStack($route, $request); return $this->prepareResponse($request, $response);//prepareResponse()方法被调用2次,原因未知 #调用runRouteWithinStack(Route $route, Request $request) return (new Pipeline($this->container)) ->send($request) ->through($middleware) ->then(function ($request) use ($route) { return $this->prepareResponse( $request, $route->run() ); }); #调用Illuminate\Routing\Route的runController()方法: return (new ControllerDispatcher($this->container))->dispatch( $this, $this->getController(), $this->getControllerMethod() ); #调用Illuminate\Routing\ControllerDispatcher的dispatch(Route $route, $controller, $method)方法: $parameters = $this->resolveClassMethodDependencies( $route->parametersWithoutNulls(), $controller, $method ); if (method_exists($controller, 'callAction')) { return $controller->callAction($method, $parameters); } return $controller->{$method}(...array_values($parameters));