Laravel源码解析:框架总览

Laravel 是一个非常简洁、优雅的 PHP 开发框架,在国内外颇为流行。在 Laravel 中除了提供最为中心的 Ioc 容器之外,还提供了强大的路由、数据库模型等常用功能模块。

一、请求生命周期

1,Laravel 框架采用了单一入口模式,应用的请求入口文件是:public/inde.php。用户配置 Web 服务器(Apache / Nginx)引导请求至该文件。这里是框架加载其他部分的起点。

2,自动加载类文件:Laravel 通过 composer 进行依赖管理,并在bootstrap/autoload.php中注册了Composer Auto Loader (PSR-4),应用中类的命名空间将被映射到类文件实际路径,不再需要开发者手动导入各种类文件,而由自动加载器自行导入。因此,Laravel允许你在应用中定义的类可以自由放置在Composer Auto Loader能自动加载的任何目录下,但大多数时候还是建议放置在app目录下或app的某个子目录下。

3,创建服务容器:从 bootstrap/app.php脚本中检索 Laravel 应用程序实例 $app。 Laravel 本身采取的第一个动作是创建一个应用程序 / 服务容器。

4,创建 HTTP / Console 内核:传入的请求经过 HTTP / Console 内核预处理,而这两个内核是用来作为所有请求都要通过的中心位置。HTTP 内核继承自 Illuminate\Foundation\Http\Kernel 类,内核是完成应用引导、请求处理(包括通过 Router 转达请求等)的场所。

该类定义了一个 bootstrappers 数组。 这个数组中的类在请求被执行前运行,这些 bootstrappers 配置了错误处理, 日志, 检测应用环境,以及其它在请求被处理前需要执行的任务。

HTTP 内核还定义了所有请求被应用程序处理之前必须经过的 HTTP 中间件,这些中间件处理 HTTP 会话读写、判断应用是否处于维护模式、 验证 CSRF 令牌等等。

HTTP 内核的 handle 方法签名相当简单:获取一个 Request ,返回一个 Response。可以把该内核想象作一个代表整个应用的大黑盒子,输入 HTTP 请求,返回 HTTP 响应。

5,载入服务提供者:在内核启动中最重要的动作之一就是载入服务提供者到你的$app(应用程序实例),即所有的服务提供者都需要挂载到服务容器下去执行。服务提供者负责引导启动框架的全部各种组件,例如数据库、队列、验证器以及路由组件。所有的服务提供者都配置在 config/app.php 文件中的 providers 数组中。首先,所有提供者的 register 方法会被调用;一旦所有提供者注册完成,接下来,boot 方法将会被调用。

6,请求调度:一旦应用完成引导和所有服务提供者都注册完成,Request 将会移交给Router进行分发。在通过Router转发请求时,所有请求都必须先经过全局HTTP中间件栈的处理,再调度到Router并获得其回调,然后执行该回调。

7,发送响应并结束:由Response发送响应,然后由内核发出terminate,包括调用可终止的中间件(定义了terminate方法的全局HTTP中间件和路由中间件)、 $app 服务容器终止。

至此,完成了一个请求的所有整个过程。

二、核心概念

接下来整理了 Laravel 框架中的几个核心概念,在此进行梳理,以便在整体上对 Laravel 有一个较为全面的理解,后续会对相关内容进行详细解读。

1,服务容器和服务提供者

服务容器是 Laravel 管理类依赖和运行依赖注入的有力工具,在类中可通过 $this->app 来访问容器,在类之外通过 $app 来访问容器;服务提供者是 Laravel 应用程序引导启动的中心,关系到服务提供者自身、事件监听器、路由的启动运行。因为应用程序中注册的路由通过RouteServiceProvider实例来加载,而事件监听器在EventServiceProvider类中进行注册。

在新创建的应用中,AppServiceProvider 文件中方法实现都是空的,这个提供者是你添加应用专属的引导和服务的最佳位置,当然,对于大型应用你可能希望创建几个服务提供者,每个都具有粒度更精细的引导。服务提供者在 config/app.php 配置文件中的providers数组中进行注册。

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * 在容器中注册绑定
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection(config('riak'));
        });
    }
}

2,门面(Facades)

Facades 为应用的服务容器提供了一个「静态」 接口。Laravel 自带了很多 Facades,可以访问绝大部分功能。Laravel Facades 实际是服务容器中底层类的 「静态代理」 ,相对于传统静态方法,在使用时能够提供更加灵活、更加易于测试、更加优雅的语法

所有的 Laravel Facades 都定义在 Illuminate\Support\Facades 命名空间下。所以,我们可以轻松的使用 Facade :

use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});

3,契约(Contract)

Laravel 的契约是指框架提供的一系列定义核心服务的接口。例如 Illuminate\Contracts\Queue\Queue 契约定义了队列任务需要实现的方法,而 Illuminate\Contracts\Mail\Mailer 契约定义了发送邮件所需要实现的方法。

每一个契约都有框架提供相应的实现。例如 Laravel 为队列提供了多个驱动的实现,邮件则由 SWiftMailer 驱动实现。

所有的契约都有其对应的 GitHUb 仓库。这为所有可用的契约提供了一个快速入门的指南,同时也可以单独作为低耦合的扩展包被开发者使用。

猜你喜欢

转载自blog.csdn.net/Struggle_linzi/article/details/86673330