Laravel源码解析--看看Lumen到底比Laravel轻在哪里
在前面一篇《Laravel源码解析--Laravel生命周期详解》中我们利用xdebug详细了解了下Laravel一次请求中到底做了哪些处理。今天我们跟 Lumen 对比下,看看 Lumen 比 Laravel 轻在哪里?
1、Lumen生命周期
相比于Laravel,在Lumen中,你对框架有着更多的控制权。Lumen的入口文件相比于Laravel要简单许多。
<?php /*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| First we need to get an application instance. This creates an instance
| of the application / container and bootstraps the application so it
| is ready to receive HTTP / Console requests from the environment.
|
*/ $app = require __DIR__.'/../bootstrap/app.php'; /*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/ $app->run();
同样的,我们先看下 bootstrap/app.php 文件。
// 1、毫无疑问,首先加载自动加载
require_once __DIR__.'/../vendor/autoload.php'; // 2、将根目录下的.env文件中的配置加载到$_ENV、$_SERVER和putfile()中,对Laravel生命周期有印象的应该还记得
// Laravel中是在$bootstrappers数组中,先加载.ENV文件,然后再加载config/*.php里的所有配置文件。
// 而在Lumen中,默认只加载了.ENV中的文件,你可以将所有的配置信息都写在.ENV文件中,然后在项目中可以用env()方法获取。
// 当然,你也可以像Laravel那样,将所有的配置信息放到config/*.php下面,不过这需要你在获取$app实例后手动调用$app->configure('api');方法。
// 这里就是Lumen比Laravel轻的一个地方,但我感觉只使用.ENV文件或config配置都不太合理,还是两个配合使用最为方便。所以这里Lumen就不会比Laravel轻了。
try {
(new Dotenv\Dotenv(dirname(__DIR__)))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
//
} /*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| Here we will load the environment and create the application instance
| that serves as the central piece of this framework. We'll use this
| application as an "IoC" container and router for this framework.
|
*/
// 3、创建Lumen App实例
$app = new Laravel\Lumen\Application(
dirname(__DIR__)
);
创建Lumen实例的时候,肯定也做了一些初始化工作。
/**
* Create a new Lumen application instance.
*
* @param string|null $basePath
* @return void
*/
public function __construct($basePath = null)
{
// 设置时区
if (! empty(env('APP_TIMEZONE'))) {
date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
}
// 设置路径
$this->basePath = $basePath;
// 向容器中的instances中绑定app,path,env,config等,并绑定一些aliases
$this->bootstrapContainer();
// 注册错误处理
$this->registerErrorHandling();
// 向容器中注入Router
$this->bootstrapRouter();
}
相比Laravel,Lumen做的初始化工作要少很多--包自动发现、路径的注册、一些基础服务提供者的注册、注册aliases时也少了很多。得到App实例后,让我们继续回头看 bootstraps/app.php 中去。
// 3、创建Lumen App实例
$app = new Laravel\Lumen\Application(
dirname(__DIR__)
); // 4、如果你需要在应用中使用门面方法,则取消此行注释
// $app->withFacades(); // 5、如果你想要在应用中使用Eloquent,则取消此行注释
// $app->withEloquent(); /*
|--------------------------------------------------------------------------
| Register Container Bindings
|--------------------------------------------------------------------------
|
| Now we will register a few bindings in the service container. We will
| register the exception handler and the console kernel. You may add
| your own bindings here if you like or you can make another file.
|
*/
// 6、注册容器绑定,绑定异常处理类的实现和Console的实现。
// 相比Laravel,Lumen少绑定了一个Http\Kernel的实现
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
); $app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
); /*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/ // 7、每个request都需要通过的一个中间件组,相比Laravel,少了一些固定要走的中间件,那么如果你把Laravel中固定的中间件注释掉,是不是就一样了呢?
// $app->middleware([
// App\Http\Middleware\ExampleMiddleware::class
// ]); // 8、注册路由中间件,同样在Laravel中,也默认定义了很多路由中间件
// $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class,
// ]); /*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/ // 9、按需注册服务提供者,而在Laravel中,除了注册了几个基础的服务提供在,还会注册config/app.php中providers数组里所有的服务提供者。
// 还是那句话,如果你把config/app.php中providers数组中都注释掉呢?对了,在Laravel5.5引入包自动发现后,它还会注册bootstrap/cache/packages.php中的服务提供者
$app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
$app->register(App\Providers\EventServiceProvider::class); /*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/
// 10、注册路由
$app->router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) {
require __DIR__.'/../routes/web.php';
}); // 11、返回App实例
return $app;
到这里,整个Lumen应用已经初始化完毕。之后 $app->run(); 其实就是根据之前注册的路由(执行每个服务提供者的boot()方法,也在这个方法中),然后进行路由分发。这与Laravel并没有什么太大区别。
综上所述,我们总结一下Lumen应用比Laravel在哪些方面轻了。
- 关于.ENV文件和config配置文件的加载,但实际上更建议将Lumen的与Laravel的保持一致
- 在new App实例的时候,Lumen所做的初始化工作,比Laravel少了一些,例如,包自动发现,路径的注册,基本服务提供者和一些aliases等。
- 关于request需要通过默认中间件。但其实我觉得有些还是必要的,比如\App\Http\Middleware\CheckForMaintenanceMode::class, 和\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, 等。
- 我个人认为应该是相比与Laravel,耗时最多的一个,就是对各种服务提供者的注册和引导(执行boot()方法)。
下面做个测试,当不对Laravel做任何处理的时候,看看启动需要多久?
Route::get('/', function () {
$end = microtime(true);
return $end - LARAVEL_START;
// return view('welcome');
});
差不多是在 0.16353797912598 秒左右。而Lumen在开启一些基本的服务后的启动时间为 0.043106079101562 ,与Laravel相差了将近有4倍。相当于光启动框架,任何逻辑处理都还没开始,Laravel比Lumen多耗时0.12s。如果我们利用一些Laravel的性能优化策略,比如缓存配置文件等会稍稍减少Laravel的启动时间 0.12118005752563 。因为php的特性,每一个request,都需要将之前的所有动作执行一遍,所以App的启动还是一个比较耗时的任务。
这时候我就想安利一下颠覆php的拓展--swoole。下一章会讲解给Laravel插上翅膀的一个用swoole做的composer包。
Laravel源码解析--看看Lumen到底比Laravel轻在哪里的更多相关文章
- laravel源码解析
本专栏系列文章已经收录到 GitBooklaravel源码解析 Laravel Passport——OAuth2 API 认证系统源码解析(下)laravel源码解析 Laravel Passport ...
- Laravel源码解析之model(代码)
本篇文章给大家带来的内容是关于Laravel源码解析之model(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 提前预祝猿人们国庆快乐,吃好.喝好.玩好,我会在电视上看 ...
- Laravel源码解析之反射的使用
前言 PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法.成员,而反射类则是拆封类中的所有方法.成员变量,并包括私有方法等.就如"解刨"一样,我们可以调用任何关键字修饰 ...
- Laravel源码解析 — 服务容器
前言 本文对将系统的对 Laravel 框架知识点进行总结,如果错误的还望指出 阅读书籍 <Laravel框架关键技术解析> 陈昊 学习课程 Laravel5.4快速开发简书网站 轩脉刃 ...
- Laravel源码解析之从入口开始
前言 提升能力的方法并非使用更多工具,而是解刨自己所使用的工具.今天我们从Laravel启动的第一步开始讲起. 入口文件 laravel是单入口框架,所有请求必将经过index.php define( ...
- laravel 读写分离源码解析
前言:上一篇我们说了<laravel 配置MySQL读写分离>,这次我们说下,laravel的底层代码是怎样实现读写分离的. 一.实现原理 说明: 1.根据 database.php ...
- Laravel学习笔记之Session源码解析(上)
说明:本文主要通过学习Laravel的session源码学习Laravel是如何设计session的,将自己的学习心得分享出来,希望对别人有所帮助.Laravel在web middleware中定义了 ...
- Laravel框架下路由的使用(源码解析)
本篇文章给大家带来的内容是关于Laravel框架下路由的使用(源码解析),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 我的解析文章并非深层次多领域的解析攻略.但是参考着开发文 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
随机推荐
- bootstrap-table sum总数量统计
写了一个分页要显示数据中所有金额的总数 但是使用 footerformatter 却不知道该怎么赋值 没办法只能放到页脚了 先上个效果图: 这样做要修改源码: bootstrap-table. ...
- spring boot(1)-Hello World
spring boot简介 spring boot是由spring官方推出的一个新框架,对spring进行了高度封装,是spring未来的发展方向.spring boot功用众多,其中最主要的功能就是 ...
- 《IT老外在中国》第11期:首次访华的编程巨匠、C#之父Anders
见到Anders的时候,他正专注的倾听国内开发者的提问,一副远视眼镜斜歪着架在头顶,宽松的深蓝色休闲毛衫随意套在白色圆领T恤外. 如果不是他那专注的神情,以及现场见证开发者对他的狂热崇拜,很难想象这位 ...
- SCOM发送邮件通知
运行方式配置:1. 新建账户--Windows域账户,安全级别较高,将其分发到SCOM管理服务器2. 配置文件--通知账户--将上一步新建的账户添加到该配置文件中的 运行方式账户,管理 所有目标对象 ...
- August 02nd 2017 Week 31st Wednesday
Love means never having to say you are sorry. 爱就是永远不必说对不起. If there is ture love, you will never do ...
- jQuery中的$.grep()使用
grep()方法用于数组元素过滤筛选 grep(array,callback,invert) array:待过滤数组; callback:处理数组中的每个元素,并过滤元素,该函数中包含两个参数,第一个 ...
- JavaScript 变量声明提升
JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.swi ...
- facebook页面种简单测试js调用flash开放的js接口的方法
无意间折腾出来的,此方法很triky,但是很简单有效. 背景说明: facebook种内嵌的iframe无法直接访问. 解决方法: chrome浏览器为例 1.右键查看iframe源代码,此时进入if ...
- js调用echarts getImage方法 将图表转换为img
function chart(opt,id,chartName){//配置option的方法 var chartName = echarts.init(document.getElementById( ...
- python爬虫Jenkins编译失败的日志
背景:在Jenkins编译失败后,需要拿到Jenkins的编译失败的日志,存储在数据库中,在把数据取出来,在另外一个页面进行展示,我的思路为: 1.观看Jenkins编译失败后的控制台显示的内容 2. ...