您现在的位置是:网站首页> 内容页

Laravel源码解析--看看Lumen到底比Laravel轻在哪里

  • 点击进去铜雀台娱乐
  • 2019-06-28
  • 392人已阅读
简介在前面一篇《Laravel源码解析--Laravel生命周期详解》中我们利用xdebug详细了解了下Laravel一次请求中到底做了哪些处理。今天我们跟 Lumen 对比下,看看 Lu

在前面一篇《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 DotenvDotenv(dirname(__DIR__)))->load()} catch (DotenvExceptionInvalidPathException $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 LaravelLumenApplication( 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中绑定apppathenvconfig等,并绑定一些aliases $this->bootstrapContainer()     // 注册错误处理 $this->registerErrorHandling()     // 向容器中注入Router $this->bootstrapRouter() }

相比Laravel,Lumen做的初始化工作要少很多--包自动发现、路径的注册、一些基础服务提供者的注册、注册aliases时也少了很多。得到App实例后,让我们继续回头看 bootstraps/app.php 中去。

// 3、创建Lumen App实例$app = new LaravelLumenApplication( 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少绑定了一个HttpKernel的实现$app->singleton( IlluminateContractsDebugExceptionHandler::class AppExceptionsHandler::class)$app->singleton( IlluminateContractsConsoleKernel::class AppConsoleKernel::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([// AppHttpMiddlewareExampleMiddleware::class// ])// 8、注册路由中间件,同样在Laravel中,也默认定义了很多路由中间件// $app->routeMiddleware([// "auth" => AppHttpMiddlewareAuthenticate::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(AppProvidersAppServiceProvider::class) $app->register(AppProvidersAuthServiceProvider::class) $app->register(AppProvidersEventServiceProvider::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" => "AppHttpControllers"] 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需要通过默认中间件。但其实我觉得有些还是必要的,比如AppHttpMiddlewareCheckForMaintenanceMode::class 和IlluminateFoundationHttpMiddlewareValidatePostSize::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包。

文章评论

Top