1. 程式人生 > >laravel5.5源碼閱讀草稿——入口

laravel5.5源碼閱讀草稿——入口

另一個 模型 monitor onf epo 關系 monit make gis

laravel的啟動需要通過路由、中間件、控制器、模型、視圖最後出現在瀏覽器。而路由、中間件、模型,這些功能都有自己的類,比如Route::any()、DB::table()、$this->middleware()等等,這些功能都是由一個叫IOC(服務容器)的對象來調配的。 它就像框架裏的一個管家,我們需要某些功能的時候不需要去自己new、去考慮運行這A對象還需要把哪些對象傳入A對象裏才能運行了。laravel的index入口文件只管制造一個ioc實例,然後把request對象傳入其中。 ioc容器中有一個叫provider的概念,大多數功能都有一個provider,它的作用就是把一個功能需要用到的類,這些類的路徑及所需要的一些東西記錄起來,在ioc實例化的時候調用其中一些基礎服務。ioc在實例化的時候,會把一些基礎的provider調用起來,這些基礎provider又調用了自身的初始化函數,來實現了一些自動化功能。 在public/index.php文件內,laravel首先加載了autoload方法,似乎是通過composer的方式實現的; 隨後引入bootstrap/app.php文件,文件內實例化了application類,並通過該應用實例註冊了Http、Kernel、Handler的共享綁定。 再看application類,繼承自Container類,並繼承了ApplicationContract接口(另一個application類,應該是實現了部分系統方法),與http核心接口(這裏通過symfony的請求與響應類來實現接口) 插一張不知道從哪盜來的Application的繼承關系圖 技術分享圖片

在laravel把系統基礎核心初始化完畢後,便通過application 的 make 方法,傳入了http核心的類名來獲取別名(在container類的aliases屬性中,存儲了眾多類名與別名的鍵值對,似乎是通過類名到別名,再到實例的方式來獲取的,數組見下方)

技術分享圖片
 1 container->aliases 
 2 = 
 3 array:64 [▼
 4   "Illuminate\Foundation\Application" => "app"
 5   "Illuminate\Contracts\Container\Container" => "app"
 6   "Illuminate\Contracts\Foundation\Application" => "app"
 7
"Psr\Container\ContainerInterface" => "app" 8 "Illuminate\Auth\AuthManager" => "auth" 9 "Illuminate\Contracts\Auth\Factory" => "auth" 10 "Illuminate\Contracts\Auth\Guard" => "auth.driver" 11 "Illuminate\View\Compilers\BladeCompiler" => "blade.compiler" 12 "Illuminate\Cache\CacheManager" => "cache" 13
"Illuminate\Contracts\Cache\Factory" => "cache" 14 "Illuminate\Cache\Repository" => "cache.store" 15 "Illuminate\Contracts\Cache\Repository" => "cache.store" 16 "Illuminate\Config\Repository" => "config" 17 "Illuminate\Contracts\Config\Repository" => "config" 18 "Illuminate\Cookie\CookieJar" => "cookie" 19 "Illuminate\Contracts\Cookie\Factory" => "cookie" 20 "Illuminate\Contracts\Cookie\QueueingFactory" => "cookie" 21 "Illuminate\Encryption\Encrypter" => "encrypter" 22 "Illuminate\Contracts\Encryption\Encrypter" => "encrypter" 23 "Illuminate\Database\DatabaseManager" => "db" 24 "Illuminate\Database\Connection" => "db.connection" 25 "Illuminate\Database\ConnectionInterface" => "db.connection" 26 "Illuminate\Events\Dispatcher" => "events" 27 "Illuminate\Contracts\Events\Dispatcher" => "events" 28 "Illuminate\Filesystem\Filesystem" => "files" 29 "Illuminate\Filesystem\FilesystemManager" => "filesystem" 30 "Illuminate\Contracts\Filesystem\Factory" => "filesystem" 31 "Illuminate\Contracts\Filesystem\Filesystem" => "filesystem.disk" 32 "Illuminate\Contracts\Filesystem\Cloud" => "filesystem.cloud" 33 "Illuminate\Contracts\Hashing\Hasher" => "hash" 34 "Illuminate\Translation\Translator" => "translator" 35 "Illuminate\Contracts\Translation\Translator" => "translator" 36 "Illuminate\Log\Writer" => "log" 37 "Illuminate\Contracts\Logging\Log" => "log" 38 "Psr\Log\LoggerInterface" => "log" 39 "Illuminate\Mail\Mailer" => "mailer" 40 "Illuminate\Contracts\Mail\Mailer" => "mailer" 41 "Illuminate\Contracts\Mail\MailQueue" => "mailer" 42 "Illuminate\Auth\Passwords\PasswordBrokerManager" => "auth.password" 43 "Illuminate\Contracts\Auth\PasswordBrokerFactory" => "auth.password" 44 "Illuminate\Auth\Passwords\PasswordBroker" => "auth.password.broker" 45 "Illuminate\Contracts\Auth\PasswordBroker" => "auth.password.broker" 46 "Illuminate\Queue\QueueManager" => "queue" 47 "Illuminate\Contracts\Queue\Factory" => "queue" 48 "Illuminate\Contracts\Queue\Monitor" => "queue" 49 "Illuminate\Contracts\Queue\Queue" => "queue.connection" 50 "Illuminate\Queue\Failed\FailedJobProviderInterface" => "queue.failer" 51 "Illuminate\Routing\Redirector" => "redirect" 52 "Illuminate\Redis\RedisManager" => "redis" 53 "Illuminate\Contracts\Redis\Factory" => "redis" 54 "Illuminate\Http\Request" => "request" 55 "Symfony\Component\HttpFoundation\Request" => "request" 56 "Illuminate\Routing\Router" => "router" 57 "Illuminate\Contracts\Routing\Registrar" => "router" 58 "Illuminate\Contracts\Routing\BindingRegistrar" => "router" 59 "Illuminate\Session\SessionManager" => "session" 60 "Illuminate\Session\Store" => "session.store" 61 "Illuminate\Contracts\Session\Session" => "session.store" 62 "Illuminate\Routing\UrlGenerator" => "url" 63 "Illuminate\Contracts\Routing\UrlGenerator" => "url" 64 "Illuminate\Validation\Factory" => "validator" 65 "Illuminate\Contracts\Validation\Factory" => "validator" 66 "Illuminate\View\Factory" => "view" 67 "Illuminate\Contracts\View\Factory" => "view" 68 ]
View Code http_kernel 的 bings屬性為container容器所綁定 kernel obj的回調函數為容器自身所創建,在創建過程中,將一些回調函數進行綁定,並觸發,但在index頁面第一次初始化時,並沒有回調函數被綁定觸發,obj創建的過程還是不清楚。創建出的kernel對象裏存儲的是系統初始化所需的各種中間件與服務供應者的類名全稱,見下方 index文件返回的kernel核心只是app/http/kernel的對象。而kernel核心在實例化時,依賴了application與route兩個對象。並將自身的$middlewareGroups、routeMiddleware數組解析進了route對象裏,在路由進行調用的時候就會把路由方法上綁定的中間件名在這裏解析出實例來調用了,其中routeMiddleware為別名所用。

在創建出kernel實例後,通過其父類的handle方法加載了provider的基類,其加載了bootstrap引導函數。 依次執行$bootstrappers中每一個bootstrapper的bootstrap()函數
$bootstrappers = [
             ‘Illuminate\Foundation\Bootstrap\DetectEnvironment‘,
             ‘Illuminate\Foundation\Bootstrap\LoadConfiguration‘,
             ‘Illuminate\Foundation\Bootstrap\ConfigureLogging‘,
             ‘Illuminate\Foundation\Bootstrap\HandleExceptions‘,
             ‘Illuminate\Foundation\Bootstrap\RegisterFacades‘,
             ‘Illuminate\Foundation\Bootstrap\RegisterProviders‘,
             ‘Illuminate\Foundation\Bootstrap\BootProviders‘,
            ];

上面bootstrap中會分別執行每一個bootstrapper的bootstrap方法來引導啟動應用程序的各個部分 1. DetectEnvironment 檢查環境 2. LoadConfiguration 加載應用配置 3. ConfigureLogging 配置日至 4. HandleException 註冊異常處理的Handler 5. RegisterFacades 註冊Facades 6. RegisterProviders 註冊Providers 7. BootProviders 啟動Providers 啟動應用程序的最後兩步就是註冊服務提供者和啟動提供者,先來看註冊服務提供器,服務提供器的註冊由類\Illuminate\Foundation\Bootstrap\RegisterProviders::class負責,該類用於加載所有服務提供器的 register 函數,並保存延遲加載的服務的信息,以便實現延遲加載。 所有服務提供器都在配置文件 app.php 文件的 providers 數組中。類 ProviderRepository 負責所有的服務加載功能: loadManifest()會加載服務提供器緩存文件services.php,如果框架是第一次啟動時沒有這個文件的,或者是緩存文件中的providers數組項與config/app.php裏的providers數組項不一致都會編譯生成services.php。 Illuminate\Foundation\Http\Kernel 的 dispatchToRouter 方法返回的閉包函數裏包含了調用請求的代碼。這段代碼指向了Illuminate\Routing\router類 Illuminate\Routing\Route類的runCallable方法裏對路由進行了調用 控制器和方法是從路由文件中獲取到的(通過symfony的request對象獲取到pathinfo),依然是通過字符串解析為類名和方法名,隨後通過ioc容器實例化類為對象,再調用控制器基類的某個方法執行傳入的方法名 Illuminate\Routing\ControllerDispatcher類的dispatch方法為真正執行的部分 插一張流程圖 技術分享圖片

laravel5.5源碼閱讀草稿——入口