Laravel 5.1 源码阅读笔记
by Liigo. 20151105. 安装,和创建项目,都是通过Composer,简单,略过。 Entry && Kernel网站入口文件,${Laravel-project}/public/index.php: $app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(IlluminateContractsHttpKernel::class);
$response = $kernel->handle(
$request = IlluminateHttpRequest::capture()
);
$response->send();
$kernel->terminate($request,$response);
生成Request,处理Request( 注意 interface Kernel {
public function bootstrap();
public function handle($request);
public function terminate($request,$response);
public function getApplication();
}
可见入口文件中的代码, 可是 $app 是谁创建的呢?是什么类型呢? Bootstrap && Application入口文件的第一行代码: $app = require_once __DIR__.'/../bootstrap/app.php';
引导我们去查看 bootstrap/app.php 源码,代码不多,都拿过来看看吧: $app = new IlluminateFoundationApplication(
realpath(__DIR__.'/../')
);
$app->singleton(
IlluminateContractsHttpKernel::class,
AppHttpKernel::class
);
$app->singleton(
IlluminateContractsConsoleKernel::class,
AppConsoleKernel::class
);
$app->singleton(
IlluminateContractsDebugExceptionHandler::class,
AppExceptionsHandler::class
);
return $app;
第一行创建,最后一行返回。现在我们知道啦, 自然, /** * Resolve the given type from the container. * (Overriding Container::make) * @return mixed */
public function make($abstract,array $parameters = [])
{
$abstract = $this->getAlias($abstract);
if (isset($this->deferredServices[$abstract])) {
$this->loadDeferredProvider($abstract);
}
return parent::make($abstract,$parameters);
}
然而还是不清楚它具体返回哪个类型。 对照前面bootstrap的代码: $app->singleton(
IlluminateContractsHttpKernel::class,
AppHttpKernel::class
);
我们推论得出: 现在我们初步总结一下:先new出Application类型对象
附加:$app是被直接new出来的( public function __construct($basePath = null)
{
$this->instance('app',$this);
$this->instance('IlluminateContainerContainer',$this);
$this->register(new EventServiceProvider($this));
$this->register(new RoutingServiceProvider($this));
// ...
$this->setBasePath($basePath);
}
Kernel::handle() && Request=>Response下一步我想知道 前面我们已经分析过了,$kernel的真实类型是 拿来 public function handle($request)
{
try {
$request->enableHttpMethodParameterOverride();
$response = $this->sendRequestThroughRouter($request);
} catch (...) {
// ...
}
$this->app['events']->fire('kernel.handled',[$request,$response]);
return $response;
}
上面代码中我感兴趣的只有 /** * Send the given request through the middleware / router. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request',$request);
Facade::clearResolvedInstance('request');
$this->bootstrap(); //! Note: $kernel->bootstrap();
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
上面代码中最后一行是我们关注的重点,它把Request送进一个新创建的流水线(Pipeline), Pipeline && Middleware && Router流水线,中间件,路由器。 Pipleline流水线 简单推断来说,其工作内容是:依次调用各中间件的 Middleware中间件 interface Middleware
{
/** * Handle an incoming request. * * @param IlluminateHttpRequest $request * @param Closure $next * @return mixed */
public function handle($request,Closure $next);
}
其文档也极其简陋,看不出太多有价值的信息。第二个参数什么意思,返回值什么意思,鬼才能看出来。可能需要从其他地方入手研究中间件。 Router将请求派发给Router的调用流程: 其中 有必要先看一下Router是怎样创建出来的。调用流程: protected function registerRouter() {
$this->app['router'] = $this->app->share(function ($app) {
return new Router($app['events'],$app);
});
}
Unresolved流水线怎么调用中间件,怎么派发给路由器,路由器又是怎么工作的呢?这中间有很多细节还没搞明白。 流水线那里,代码很绕,暂时无法理解。中间件那里,文档太简陋,暂时无法理解。路由器运行原理那里,暂时还没有去看代码。 目前就是这个样子,此文到此为止吧。我想我需要去看一下Laravel 5.1的基础文档,然后再回头去读源码,可能效果会更好。 补记Bootstrap我之前在分析 /** * Bootstrap the application for HTTP requests. * * @return void */
public function bootstrap()
{
if (! $this->app->hasBeenBootstrapped()) {
$this->app->bootstrapWith($this->bootstrappers());
}
}
/** * Run the given array of bootstrap classes. * * @param array $bootstrappers * @return void */
public function bootstrapWith(array $bootstrappers)
{
$this->hasBeenBootstrapped = true;
foreach ($bootstrappers as $bootstrapper) {
$this['events']->fire('bootstrapping: '.$bootstrapper,[$this]);
$this->make($bootstrapper)->bootstrap($this);
$this['events']->fire('bootstrapped: '.$bootstrapper,[$this]);
}
}
/**
* The bootstrap classes for the application.
*
* @var array
*/
protected $bootstrappers = [ 'IlluminateFoundationBootstrapDetectEnvironment','IlluminateFoundationBootstrapLoadConfiguration','IlluminateFoundationBootstrapConfigureLogging','IlluminateFoundationBootstrapHandleExceptions','IlluminateFoundationBootstrapRegisterFacades','IlluminateFoundationBootstrapRegisterProviders','IlluminateFoundationBootstrapBootProviders',];
以其中 public function registerConfiguredProviders() {
$manifestPath = $this->getCachedServicesPath();
(new ProviderRepository($this,new Filesystem,$manifestPath))
->load($this->config['app.providers']);
}
其中 'providers' => [
/*
* Laravel Framework Service Providers...
*/
IlluminateFoundationProvidersArtisanServiceProvider::class,IlluminateAuthAuthServiceProvider::class,IlluminateBroadcastingBroadcastServiceProvider::class,IlluminateBusBusServiceProvider::class,IlluminateCacheCacheServiceProvider::class,IlluminateFoundationProvidersConsoleSupportServiceProvider::class,IlluminateRoutingControllerServiceProvider::class,IlluminateCookieCookieServiceProvider::class,IlluminateDatabaseDatabaseServiceProvider::class,IlluminateEncryptionEncryptionServiceProvider::class,IlluminateFilesystemFilesystemServiceProvider::class,IlluminateFoundationProvidersFoundationServiceProvider::class,IlluminateHashingHashServiceProvider::class,IlluminateMailMailServiceProvider::class,IlluminatePaginationPaginationServiceProvider::class,IlluminatePipelinePipelineServiceProvider::class,IlluminateQueueQueueServiceProvider::class,IlluminateRedisRedisServiceProvider::class,IlluminateAuthPasswordsPasswordResetServiceProvider::class,IlluminateSessionSessionServiceProvider::class,IlluminateTranslationTranslationServiceProvider::class,IlluminateValidationValidationServiceProvider::class,IlluminateViewViewServiceProvider::class,/*
* Application Service Providers...
*/
AppProvidersAppServiceProvider::class,AppProvidersAuthServiceProvider::class,AppProvidersEventServiceProvider::class,AppProvidersRouteServiceProvider::class,],
大家都看到了,Kernel和Application互相交叉调用,Bootstrap过程又穿插在Request处理过程中间。暂时看不出清晰的思路。 ReferencesLaravel不是一个小项目,逻辑复杂,划分模块之后,布局分散。你很难在短时间内仅仅通过浏览源代码理清框架主体设计思路,尤其是在本人对Laravel还十分陌生的情况下。适可而止是理智的选择。 还是先看一下基础性的文档吧:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |