使用 eloquent orm
TRANSCRIPT
Laravel 工作坊使用 Eloquent ORM
shengyou @ 彰師大資工系學會 (2014.12.07)
階段任務• 學習 Eloquent ORM 的使用方式,了解
Laravel 操作資料庫的方法
• 學習如何使用 artisan tinker、dd() 等工具來協助測試 Model 程式碼
使用 Eloquent ORM
什麼是 ORM?• ORM = Object-relational mapping
• 簡單來說,就是把資料庫裡一筆一筆的資料變成物件來操作。這些物件透過繼承可以增加更多的方法,讓資料庫的操作
(CRUD) 更加直覺、方便
為什麼要用 ORM?• 原本在寫資料庫查詢時,往往需要自行依照需求撰寫 SQL 查詢式,當查詢式變長、關聯日趨複雜時,很難直覺了解該查詢式的作用
• 自行處理 SQL 查詢式時,也需確認輸入的字串是否都有 Escape 以防安全性疑慮
Model 慣例• Laravel 的相關慣例複習
- 一個 resource 對應到 DB 裡的一個 table
- 一個 model 對應到 table 裡的一個 row
- table 名稱用複數; model 名稱用單數- 從資料表取出來的東西是 Collection,可當 陣列(array) 使用
tinker 小幫手• PHP 本身有內建互動指令 (REPL) 模式,可用 php -a 進入,可在其中測試程式碼
• tinker 則是 Laravel 提供的 artisan 指令,除了進入 PHP 的 REPL 模式外,加載 Laravel
所有物件環境,可讓我們在其中測試
Laravel 的程式碼
★ tinker 說明:http://laravel-recipes.com/recipes/280/interacting-with-your-application
artisan tinker• 進入 PHP 互動模式,並載入 Laravel 環境
- 可以直接在指令模式下操作 Laravel 各元件,測試程式寫法
- 要結束請用 exit; 指令
• 範例:$ php artisan tinker[1] > exit;
★ 由於 tinker 相依的 extension pcntl 在 Windows 上沒有實作,因此無法全功能支援 tinker 功能:http://php.net/manual/en/pcntl.installation.php
dd() 測試工具• Laravel 內建一個 debug 輔助函式:dd()
- 其實就是把變數丟進 var_dump 後 exit
- 可以在任何地方使用,測試程式碼流程、邏輯、了解物件內容
• 範例:$post = Post::find(1);dd($post);
★ dd() 說明:http://laravel.com/docs/4.2/helpers#miscellaneous
新增資料• 使用 new 建構式
- 直接使用 new 建構式產生 Model 實體,再存檔
• 範例:$post = new Post;$post-‐>title = ‘My Title’;$post-‐>save();
新增資料• create($array);
- 從陣列新增資料,陣列的 key 值自動對應到資料表的欄位
• 範例:$post = Post::create($input);
Mass Assignment• Laravel 的 ORM 可以直接用 Mass
Assignment 的方式直接新增資料,語法簡潔、快速方便,但有可能會有安全性問題
• 在 generator 產生的 Model 裡,fillable 的屬性就是在設定哪些欄位可以使用 Mass
Assignment 做為防禦手段
★ 官網文件:http://laravel.tw/docs/4.2/eloquent#mass-assignment
Mass Assignment 警示
設定 fillable、guarded• 在 Model 內設定 fillable 屬性,指定哪些欄位可以透過 Mass Assignment 來寫入/更新資料
• guarded 則是相反的屬性,設定後可以保護特定欄位不使用 Mass Assignment
• 範例:protected $fillable = [‘title’, ‘content’, ‘category_id’];protected $guarded = [‘id’, ‘password’];
刪除資料• delete();
- 先取出 Model 實體後,再刪除
• 範例:$post = Post::find(1);$post-‐>delete();
刪除資料• destroy($id);
- 刪除一筆資料,使用 primary key
• destroy([1, 2, 3]);
- 刪除多筆資料,使用 array 傳值
• destroy(1, 2, 3);
- 刪除多筆資料,使用多參數傳值
更新資料• save();
• 先取出 Model 實體後,再針對屬性更新,全部完成後再存檔
• 範例:$post = Post::find(1);$post-‐>title = ‘My New Title’;$post-‐>save();
更新資料• update($array);
- 從陣列更新資料,陣列的 key 值自動對應到資料表的欄位
• 範例:$post = Post::find(1);$post-‐>update($input);
查尋資料• all() // 取出全部資料
• find($id); // 使用 primary key
• where(‘欄位’, ‘條件’, ‘值’);
• orderBy(‘欄位’, ‘排序方式’);
• get(); // 回傳 Collection
• first(); // 回傳 Model
Collection 逐筆取出• 從 Model 查詢的結果,Eloquent 會回傳一個 Collection,其行為就像陣列一樣,可以支援用 foreach 取出資料
• 範例:$posts = Post::all(); // $posts 是 Collectionforeach($posts as $post){ echo $post-‐>title; // $post 是 Model}
特異功能• paginate($per_page);
- 依設定的筆數在 Query 內加 Limit 語法,在 view 上可自動支援分頁
• random($num);
- 從 Collection 隨機取出 n 筆資料
更多 ORM 操作方式• 官方文件
- http://laravel.tw/docs/4.2/eloquent#insert-update-delete
• Collection 用法
- http://jenssegers.be/blog/51/laravel-collections-are-awesome
存檔點• 試著把現在已經可以運作的程式碼加入版本控制內
• 流程提醒:
- working directory > staging area > commit
資料表關聯
資料表間的關聯
Model 資料關聯• 在 Model 內定義其與其他 Model 間的關聯類型 Eloquent 就會自動將這個關聯變成物件間的屬性,而無需自行下 SQL 語法
• 範例:public function {另一個 Model 的名稱(單/複數)}(){ return $this-‐>{關聯類型}(‘{Model 名稱}’);}
關聯類型• belongsTo(‘Model’);
- 歸屬於另一個 Model
• hasMany(‘Model’);
- 擁有多個 Model
★ 關聯類型詳細說明:http://laravel.tw/docs/4.2/eloquent#relationships
資料關聯設定Post 關聯設定
資料關聯設定Category 關聯設定
資料關聯設定Comment 關聯設定
Model 內取用關聯• 把資料間的關聯用物件的方式去思考,即可透過 Model 的屬性值去取得關聯後的資料內容
• 範例:$post = Post::find(1);echo $post-‐>category-‐>name;foreach($post-‐>comments as $comment){ echo $comment-‐>content;}
存檔點• 試著把現在已經可以運作的程式碼加入版本控制內
• 流程提醒:
- working directory > staging area > commit
階段檢查表• 在 routes.php 內測試 Eloquent ORM 用法的 get request 規則數個
• 三個 Model 內都有對應的關聯邏輯設定
問與答學員可開始練習、實作
單元小結• 在這個單元裡,我們說明學習如何使用
Eloquent ORM 進行資料操作,並從 tinker
及 route 內了解操作結果
• 下一個單元,我們將學習 Laravel 的流程處理及 Route 設定