這篇文章整理分享六個能提升程式碼可讀性的 Laravel Eloquent 小技巧,希望對大家有幫助!
Eloquent是Laravel預設使用的ORM。採用了活動記錄模式。讓你可以以更輕鬆的方式與資料庫互動。每個單獨的模型都表示資料庫中的一個表,你可以使用該表進行操作。在這篇文章中,我們將或多或少地向你展示你可能不知道的隱藏秘密、方法和屬性,以改進你的程式碼。
蛇形命名屬性是一個有趣的屬性。讓我們看看程式碼是怎麼說的:
/** * 指示是否在数组上使用蛇形大小写属性。 * * @var bool */ public static $snakeAttributes = true;
人們經常會錯誤地使用這個屬性來更改存取屬性的方式。許多人認為,如果更改這個屬性,就可以使用駝峰式註解輕鬆存取屬性。事實並非如此。我們強烈建議你不要使用它。當模型作為陣列輸出時,只需定義屬性是駝峰式還是蛇形即可。
如果你想基於駝峰式命名,我們建議你查看Kirk Bushell 的軟體包Eloquence by Kirk Bushell.
#如果你正在使用Laravel 的Eloquent ORM,那這對你來說是個好消息。它提供了一種開箱即用的分頁方法。你可能很熟悉這樣的寫法:
$comments = Comment::paginate(20);
使用此方法,你可以每頁20個條目來為 comment model 分頁。更改該值可以定義每頁顯示多少條數。如果不指定任何內容,則套用預設值,即15。
假設您希望在網站上的多個位置顯示評論。每頁總是有30則評論。如果必須在每個地方傳遞參數30,那就麻煩了。因此,您可以直接在模型上設定新的預設值。
protected $perPage = 30;
Eloquent有一個稱為「存取器」的強大功能。這個功能允許你在模型或表格中不存在的模型中添加自訂欄位。使用現有的值或定義全新的值都不重要,隨時都可以回退。下面是存取器如何運作的範例。假設有一個名為user
的模型,我們為他新增一個FullName的存取器:
function getFullNameAttribute() { return sprintf('%s %s', $this->first_name, $this->last_name); }
現在你可以存取post模型上的full_name
屬性,如下:
User::latest()->first()->full_name;
如果傳回物件(如集合),則此屬性不會附加到使用者模型。將protected$appends
屬性加入模型中。它接受一個數組,其中包含一個或多個字段,從現在起應該自動追加這些字段。寫成這樣就可以了:
protected $appends = ['full_name'];
變因器與獲取器相反。你可以用它做些很有意思的事。舉個例子,轉換不同類型的輸入。讓我來給你詳細說。假設你想要保存一種類型的時間段。通常,你總是保存盡可能小的單位。在我們的案例中是秒。由於UX的原因,使用者不想輸入秒,例如在一個地方輸入分鐘,或在另一個地方輸入小時。這一切都可以很快解決。
class Video extends Model { public function setDurationInMinutes($value) { $this->attributes['duration_in_seconds'] = $value * 60; } public function setDurationInHours($value) { $this->attributes['duration_in_seconds'] = $value * 60 * 60; } }
上述程式碼意味著你可以使用一個不存在於資料表本身的欄位。
model中使用的是duration_in_minutes
字段,但是在後台,我們使用duration_in_seconds
進行更新,也有可能使用一個不存在字段duration_in_hours
。根據這個邏輯,我們在Controller如此調用:
class AnyController { public function store() { $video->update([ 'title' => request('title'), 'duration_in_minutes' => request('duration_in_minutes'), ]); } }
這將節省你在控制器中進行計算的時間,你可以簡單地使用不存在的列,並在執行某些計算時使用變異器
將其結果對應到正確的欄位上。
讓我們來談談關聯關係。預設情況下,Laravel使用延遲載入。就關聯關係而言,這意味著什麼?延遲載入的好處是可以節省內存,因為並不是所有的資料都需要保留,我們可以在需要的時候載入資料。如下:
$comments = Comment::all(); foreach ($comments as $comment) { echo $comment->user->name; }
在上面的範例中,我們會取得所有評論資料。然後遍歷評論並顯示每個評論的使用者名稱。這段程式碼沒什麼問題,可以正常運作,但我們遇到了一個問題。延遲加載現在確保僅當我們想要輸出用戶名時才執行獲取用戶的查詢。
歡迎來到你的第一個 N 1 問題。為什麼是 N 1? N 始終是評論的數量,1 是獲取評論的查詢。例如,如果我們有500個評論,那麼獲取所有評論的查詢被觸發一次,然後一個查詢獲得相應的user-per評論。所以500 1查詢。這意味著隨著註釋數量的增加,查詢的數量也會增加。
為了防止這種情況,有一種稱為渴求式加載的方法。
$comments = Comment::with('user')->get(); foreach ($comments as $comment) { echo $comment->user->name; }
这会以两个查询结束。第一个查询获取所有注释,第二个查询立即获取所有关联用户。在后台,会发生以下情况(简化版SQL):
SELECT id, user_id, body FROM comments; SELECT name FROM users WHERE user_id IN (1,2,3,4,5...);
不论是 10、500 还是 10000 条评论数据都不重要,我们都依旧只执行两次SQL查询。
好了,你现在已经看到如何使用渴求式加载了。但只限于如何手动使用。你还可以将整个过程自动化,以便某些关联关系总是自动通过渴求式方式加载。为此,需要给模型设定一个属性。
protected $with = [];
我们可以在Comment
model简单设置 protected $with = ['user'];
, 从现在起,user
在任何时候都会自动加载。
我们还有很多种渴求式加载,有仅加载特定列、嵌套即时加载、多个即时加载等等。更多详情请Laravel文档或深入核心。
有的时候需要查询所有的主键 ID, 查询是否复杂并不重要,大多数人可能会像这样做:
User::all()->pluck('id');
这个操作很 nice,但是返回的是一个集合,想要转换成数组的话可以使用 toArray()
。
User::all()->pluck('id')->toArray();
大多数情况下,上面的操作的可以简化成这样:
User::all()->modelKeys();
这种方式返回一个数组。重要的是这个方法并不会总是返回 id
。 顾名思义,他是以数组的形式返回所有模型主键。主键默认是id
,同时也可以在模型中定义主键名。
protected $primaryKey = 'id';
原文地址:https://laravel-news.com/6-eloquent-secrets
译文地址:https://www.php.cn/link/c7decb5ce28209911b545d0b1059c5e3
【相关推荐:laravel视频教程】
以上是6個Laravel Eloquent小技巧,幫助你提升程式碼可讀性!的詳細內容。更多資訊請關注PHP中文網其他相關文章!