laravel大致的运行过程,先记录一下。 当然我是在看到了 这个博文https://my.oschina.net/falcon10086/blog/647507,写的很棒。
laravel唯一的路口文件 /public/index.php 一步一步来看
require __DIR__.'/../bootstrap/autoload.php';引入类加载器,查看autoload.php文件
define('LARAVEL_START', microtime(true));require __DIR__.'/../vendor/autoload.php';$compiledPath = __DIR__.'/cache/compiled.php';if (file_exists($compiledPath)) { require $compiledPath;}第一行代码定义程序运行的开始事件; 第二段代码请求了vendor/autoload.php文件,也就是说使用了composer自带的类加载器。 第三段和第四段代码用来优化效率。
现在继续看index.php文件
$app = require_once __DIR__.'/../bootstrap/app.php';查看bootstrap/app.php文件
$app = new Illuminate/Foundation/application( realpath(__DIR__.'/../'));$app->singleton( Illuminate/Contracts/Http/Kernel::class, App/Http/Kernel::class);$app->singleton( Illuminate/Contracts/Console/Kernel::class, App/Console/Kernel::class);$app->singleton( Illuminate/Contracts/Debug/ExceptionHandler::class, App/Exceptions/Handler::class);return $app;先创建了一个 Illuminate/Foundation/Application 实例,该类继承Illuminate/Container/Container,调用其singleton()方法绑定接口和类,最后返回实例,这里是一个单例。
看一下 Illuminate/Foundation/Application 构造函数
public function __construct($basePath = null) { $this->registerBaseBindings(); $this->registerBaseServicePRoviders(); $this->registerCoreContainerAliases(); if ($basePath) { $this->setBasePath($basePath); } }$this->registerBaseBindings()方法
protected function registerBaseBindings() { /* * 首先需要明白当前类继承自 Illuminate/Container/Container * * setInstance 是 Illuminate/Container/Container 中的方法将类和当前对象绑定, 当然这样说是为了跟容易表示,下面的注释也是如此 */ static::setInstance($this); /* * 将'app'和当前对象放在 Illuminate/Container/Container 的 instances 数组中, * 形成一个映射,当然当前类继承自 Illuminate/Container/Container 也就是调用自己的 instance() 方法 * 这样'app'指向了当前对象,实现绑定。 */ $this->instance('app', $this); /* * 和上面的类似,绑定 */ $this->instance('Illuminate/Container/Container', $this); }$this->registerBaseServiceProviders()
protected function registerBaseServiceProviders() { /* * 依赖注入: 当前对象被注入到 EventServiceProvider、RoutingServiceProvider 中 */ $this->register(new EventServiceProvider($this)); $this->register(new RoutingServiceProvider($this)); }注册服务提供器。
$this->registerCoreContainerAliases()
public function registerCoreContainerAliases() { $aliases = [ 'app' => ['Illuminate/Foundation/Application', 'Illuminate/Contracts/Container/Container', 'Illuminate/Contracts/Foundation/Application'] ... ]; foreach ($aliases as $key => $aliases) { foreach ((array) $aliases as $alias) { $this->alias($key, $alias); } } }注册核心类的别名,简化命名; aliases 数组中一个复杂的名字对应别名。 例如下面的: Illuminate/Foundation/Application => app; Illuminate/Contracts/Container/Container => app; foreach 就是具体的绑定。
现在分析app.php中的$app->singleton()。该方法将接口和具体实现类绑定在一起,之后用到接口的时候会调用对应的具体实现。该部分源码比较复杂,可以自己看一下,主要部分是 Illuminate/Container/Container 的 make 和 build 方法。
现在再次回到index.php
$kernel = $app->make(Illuminate/Contracts/Http/Kernel::class);由于 bootstrap/app.php 中绑定了接口和具体实现,这里调用 make 就会创建App/Http/Kernel::class 类实例。
最后kernel 处理 http 请求,接收请求, 发送响应, 终止程序,处理一些收尾的工作。
新闻热点
疑难解答