2018年11月20日 星期二

《面試官別再問》Laravel框架一:原理機制篇

一. 請求週期

Laravel 採用了單一入口模式,應用的所有請求入口都是 public/index.php 文檔。

註冊類文檔自動加載器:Laravel通過composer進行依賴管理,並在bootstrap/autoload.php中註冊了Composer Auto Loader (PSR-4),應用中類的命名空間將被映射到類文檔實際路徑,不再需要開發者手動導入各種類文檔,而由自動加載器自行導入。因此,Laravel允許你在應用中定義的類可以自由放置在Composer Auto Loader能自動加載的任何目錄下,但大多數時候還是建議放置在app目錄下或app的某個子目錄下
創建服務容器:從 bootstrap/app.php 文檔中取得 Laravel 應用實例 $app (服務容器)
創建 HTTP / Console 內核:傳入的請求會被髮送給 HTTP 內核或者 console 內核進行處理,HTTP 內核繼承自 Illuminate\Foundation\Http\Kernel 類。它定義了一個bootstrappers 數組,數組中的類在請求真正執行前進行前置執行,這些引導進程配置了錯誤處理,日誌記錄,檢測應用進程環境,以及其他在請求被處理前需要完成的工作;HTTP內核同時定義了一個HTTP 中間件列表,所有的請求必須在處理前通過這些中間件處理HTTP session 的讀寫,判斷應用是否在維護模式, 驗證CSRF token 等等
載入服務提供者至容器:在內核引導啟動的過程中最重要的動作之一就是載入服務提供者到你的應用,服務提供者負責引導啟動框架的全部各種組件,例如數據庫、隊列、驗證器以及路由組件。因為這些組件引導和配置了框架的各種功能,所以服務提供者是整個 Laravel 啟動過程中最為重要的部分,所有的服務提供者都配置在 config/app.php 文檔中的 providers 數組中。首先,所有提供者的 register 方法會被調用;一旦所有提供者註冊完成,接下來,boot 方法將會被調用
分發請求:一旦應用完成引導和所有服務提供者都註冊完成,Request 將會移交給路由進行分發。路由將分發請求給一個路由或控制器,同時運行路由指定的中間件

二. 服務容器和服務提供者

服務容器是Laravel 管理類依賴和運行依賴注入的有力工具,在類中可通過$this->app 來訪問容器,在類之外通過$app 來訪問容器;服務提供者是Laravel 應用進程引導啟動的中心,關係到服務提供者自身、事件監聽器、路由以及中間件的啟動運行。應用進程中註冊的路由通過RouteServiceProvider實例來加載;事件監聽器在EventServiceProvider類中進行註冊;中間件又稱路由中間件,在app/Http/Kernel.php類文檔中註冊,調用時與路由進行綁定。在新創建的應用中,AppServiceProvider 文檔中方法實現都是空的,這個提供者是你添加應用專屬的引導和服務的最佳位置,當然,對於大型應用你可能希望創建幾個服務提供者,每個都具有粒度更精細的引導。服務提供者在 config/app.php 配置文檔中的providers數組中進行註冊

三、Artisan Console

Laravel利用PHP的CLI構建了強大的Console工具artisan,artisan幾乎能夠創建任何你想要的模板類以及管理配置你的應用,在開發和運維管理中扮演着極其重要的角色,artisan是Laravel開發不可或缺的工具。在Laravel根目錄下運行:PHP artisan list可查看所有命令行表。用好artisan能極大地簡化開發工作,並減少錯誤發生的可能;另外,還可以編寫自己的命令。下面列舉部分比較常用的命令:

啟用維護模式:php artisan down --message='Upgrading Database' --retry=60
關閉維護模式:php artisan up
生成路由緩存:php artisan route:cache
清除路由緩存:php artisan route:clear
數據庫遷移 Migrations:php artisan make:migration create_users_table --create=users
創建資源控制器:php artisan make:controller PhotoController --resource --model=Photo
創建模型及遷移:php artisan make:model User -m

四、表單驗證機制

  表單驗證在web開發中是不可或缺的,其重要性也不言而喻,也算是每個web框架的標配部件了。Laravel表單驗證擁有標準且龐大的規則集,通過規則調用來完成數據驗證,多個規則組合調用須以“|”符號連接,一旦驗證失敗將自動回退並可自動綁定視圖。

  下例中,附加bail規則至title屬性,在第一次驗證required失敗後將立即停止驗證;“.”語法符號在Laravel中通常表示嵌套包含關係,這個在其他語言或框架語法中也比較常見

$this->validate($request, [
    'title' => 'bail|required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

五、Eloquent 模型

  Eloquent ORM 以ActiveRecord形式來和數據庫進行交互,擁有全部的數據表操作定義,單個模型實例對應數據表中的一行

1 $flights = App\Flight::where('active', 1)
2 ->orderBy('name', 'desc')
3 ->take(10)
4 ->get();

config/database.php中包含了模型的相關配置項。Eloquent 模型約定:

數據表名:模型以單數形式命名(CamelCase),對應的數據表為蛇形複數名(snake_cases),模型的$table屬性也可用來指定自定義的數據表名稱
主鍵:模型默認以id為主鍵且假定id是一個遞增的整數值,也可以通過$primaryKey來自定義;如果主鍵非遞增數字值,應設置$incrementing = false
時間戳:模型會默認在你的數據庫表有 created_at 和 updated_at 字段,設置$timestamps = false可關閉模型自動維護這兩個字段;$dateFormat 屬性用於在模型中設置自己的時間戳格式
數據庫連接:模型默認會使用應用進程中配置的數據庫連接,如果你想為模型指定不同的連接,可以使用 $connection 屬性自定義
批量賦值:當用户通過 HTTP 請求傳入了非預期的參數,並藉助這些參數 create 方法更改了數據庫中你並不打算要更改的字段,這時就會出現批量賦值(Mass-Assignment)漏洞,所以你需要先在模型上定義一個 $fillable(白名單,允許批量賦值字段名數組) 或 $guarded(黑名單,禁止批量賦值字段名數組)
1 // 用屬性取回航班,當結果不存在時創建它...
2 $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
3
4 // 用屬性取回航班,當結果不存在時實例化一個新實例...
5 $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);

六、Laravel的Restful風格

  一般認為Restful風格的資源定義不包含操作,但是在Laravel中操作(動詞)也可作為一種資源來定義。下圖是對Laravel中資源控制器操作原理的描述,可以看到,create、edit就直接出現在了URI中,它們是一種合法的資源。對於create和edit這兩種資源的訪問都採用GET方法來實現,第一眼看到頓感奇怪,後來嘗試通過artisan console生成資源控制器,並注意到其對create、edit給出註釋“ Show the form for ”字樣,方知它們只是用來展現表單而非提交表單的。

沒有留言:

張貼留言