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

来源:https://www.cnblogs.com/wyycc/archive/2018/09/06/9601925.html
-Advertisement-
Play Games

laravel的啟動需要通過路由、中間件、控制器、模型、視圖最後出現在瀏覽器。而路由、中間件、模型,這些功能都有自己的類,比如Route::any()、DB::table()、$this->middleware()等等,這些功能都是由一個叫IOC(服務容器)的對象來調配的。 它就像框架里的一個管家, ...


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方法為真正執行的部分   插一張流程圖  

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題意 輸入一個整數X,求一個整數N,使得N!恰好大於$X^X$。 Sol 考試的時候只會$O(n)$求$N!$的首碼和啊。 不過最後的結論挺好玩的 $n! \approx \sqrt{2 \pi n} (\frac{n}{e})^n$ 然後就可以$O(1)$算啦 ...
  • python名片管理是我根據視頻自己敲敲的代碼,後續學習會持續更新 代碼 card_main.py card_tools.py ...
  • 集合中線程安全的類有:vector,stack,hashtable,enumeration,除此之外均是非線程安全的類與介面 Collection 是對象集合, Collection 有兩個子介面 List 和 Set, List 可以通過下標 (1,2..) 來取得值,值可以重覆,而 Set 只能 ...
  • 父類的靜態成員初始化>父類的靜態代碼塊>子類的靜態成員初始化>子類的靜態代碼塊>父類的代碼塊>父類的構造方法>子類的代碼塊>子類的構造方法 註意: 1.靜態成員和靜態代碼塊只有在類載入的時候執行一次,再次創建實例時,不再執行,因為只在方法區存在一份,屬於一整個類。 2.上述的是通用的載入順序,如果沒 ...
  • 1 import java.util.Arrays; 2 3 public class ArrayOperator { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 ArrLis... ...
  • 我們都知道HashTable是線程安全的類,因為使用了Synchronized來鎖整張Hash表來實現線程安全,讓線程獨占; ConcurrentHashMap的鎖分離技術就是用多個鎖來控制對Hash表的不同部分進行修改,因為我可能只需要對一小塊部分進行操作,而如果鎖整張表開銷太大了,其內部實現就是 ...
  • 目錄 分隔符 字元類和類型 重覆 子表達式 子表達式計數 定位到字元串的開始或末尾 分支 匹配特殊字元 特殊字元含義 分隔符 正則表達式必須包含在一對分隔符中。可以選擇任何非字母,數字,"\" 或空格的字元作為分隔符。字元串的開始和結束必須有匹配的分隔符。 最常用的分隔符是"/"。 如匹配"shop ...
  • typeHandler作用: 1.傳參時將javaType類型轉換成jdbcType 2.結果集中ResultSet中取值時,jdbcType轉換為javaType; 系統自定義的typeHandler: mybatis系統內部定義了一系列的typeHandler;基本涵蓋了我們正常使用的類型轉換; ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...