本文實例講述了Laravel框架源碼解析之入口文件原理。分享給大家供大家參考,具體如下:
前言
提升能力的方法并非使用更多工具,而是解刨自己所使用的工具。今天我們從Laravel啟動的第一步開始講起。
入口文件
laravel是單入口框架,所有請求必將經過index.php
1
|
define( 'LARAVEL_START' , microtime(true)); // 獲取啟動時間 |
使用composer是現代PHP的標志
1
|
require __DIR__. '/../vendor/autoload.php' ; // 加載composer -> autoload.php |
加載啟動文件
1
|
$app = require_once __DIR__. '/../bootstrap/app.php' ; |
獲取$app
是laravel啟動的關鍵,也可以說$app是用于啟動laravel內核的鑰匙。隨后就是加載內核,載入服務提供者、門面所映射的實體類,中間件,最后到接收http請求并返回結果。
1
2
3
4
5
6
7
8
9
|
$kernel = $app ->make(Illuminate\Contracts\Http\Kernel:: class ); // 加載核心類 $response = $kernel ->handle( $request = Illuminate\Http\Request::capture() ); $response ->send(); $kernel ->terminate( $request , $response ); |
看似短短的4行代碼,這則是laravel的優雅之處。我們開始深層次解刨。
bootstrap\app.php
這個啟動文件也可以看作是一個服務提供者,不過他并沒有boot,register方法。因為入口文件直接加載他,所有這些沒必要的方法就不存在了。
作為啟動文件,首頁則是加載框架所有必須的要要件,例如
- registerBaseBindings
- registerBaseServiceProviders
- registerCoreContainerAliases,
這其中包括了很多基礎性的方法和類,例如
-
db
[\Illuminate\Database\DatabaseManager::class]
-
auth
[\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class]
-
log
[\Illuminate\Log\LogManager::class, \Psr\Log\LoggerInterface::class]
-
queue
[\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class]
-
redis
[\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class]
-
等等
...
而$app這個在服務提供者的核心變量則就是Application實例化所得,而你在服務提供者內使用的make,bind,singleton來自他的父類Container,都說容器是laravel的核心概念。這塊的概念后續我們會詳細的講解。
1
2
3
|
$app = new Illuminate\Foundation\Application( realpath (__DIR__. '/../' ) ); |
上面我們已經獲得$app的實例化了,現在通過$app來注冊核心類、異常類,并將$app返回給index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$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 ); |
App\Http\Kernel
核心類了所有的
- 系統中間件
- 群組中間件
- 路由中間件
當然你需要使用中間件也是在這個類中加載,是經常被使用的一個文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode:: class , \Illuminate\Foundation\Http\Middleware\ValidatePostSize:: class , \App\Http\Middleware\TrimStrings:: class , \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull:: class , \App\Http\Middleware\TrustProxies:: class , ]; /** * The application's route middleware groups. * * @var array */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies:: class , \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse:: class , \Illuminate\Session\Middleware\StartSession:: class , // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession:: class , \App\Http\Middleware\VerifyCsrfToken:: class , \Illuminate\Routing\Middleware\SubstituteBindings:: class , ], 'api' => [ 'throttle:60,1' , 'bindings' , ], ]; |
這個核心類繼承自他的父類Illuminate\Foundation\Http\Kernel::class
,核心類做了很多事情,它會將所有的中間件全部存儲到一個指定的數組,方便內核調用及其他類調用。
1
2
3
4
5
6
|
namespace App\Http; use App\Api\Middleware\VerifyApiToken; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel |
回到起點
Laravel的啟動經歷了很繁瑣的一個過程。這也是Laravel優雅的關鍵點。
1
2
3
4
5
6
7
|
$response = $kernel ->handle( $request = Illuminate\Http\Request::capture() ); $response ->send(); $kernel ->terminate( $request , $response ); |
將請求傳入則完成了整個laravel的啟動,至于結果的返回則有開發者自行通過控制器或其他可訪問類返回。
希望本文所述對大家基于Laravel框架的PHP程序設計有所幫助。
原文鏈接:https://segmentfault.com/a/1190000016522619