3分鐘短文:Laravel模型讀資料的那個“障眼法”

ragus發表於2020-10-02

引言

通過前幾篇文章檢視和路由的介紹,我們通過模型物件運算元據庫表。

laravel模型的精巧設計使得我們運算元據層邏輯更加得心應手。

圖片

本文我們來說說模型在讀寫資料中所使用的技巧。

日期時間格式化

先從最常用的地方著手,比如在遷移檔案內使用的 timestamps方法,就是在表內生成 created_atupdated_at兩個 datetime 型別的欄位,用於標記該記錄的建立時間和更新時間。

laravel框架繼承了廣泛使用穩定可靠的 Carbon 類庫用於操作日期時間。為了測試方便,我們不需要寫額外的程式碼,直接使用 tinker 命令列互動工具,在命令列輸入:

tinker

進入互動介面,然後我們使用模型查詢一條 events 表的資料,並訪問其屬性:

namespace App;
$event = Event::find(1);
$event->created_at

列印 created_at 屬性輸入內容如下:

=> Illuminate\Support\Carbon {#819
    +"date": "2020-10-02 04:01:38.000000",
    +"timezone_type": 3,
    +"timezone": "Asia/Shanghai (+08:00)",
}

輸出的是一個 Carbon 物件。也可以呼叫格式化方式返回需要的格式,比如返回時間字串:

$event->created_at->toDateString()
// "2020-10-02"    

或者自定義格式:

$event->created_at->format('Y-m-d H:i')
// "2020-10-02 04:01"    

在模型內使用該格式化方式很容易,新增如下屬性定義:

protected $dates = ['created_at','updated_at','started_at'];

那麼這三個欄位都會使用 Carbon 進行格式化,在訪問模型物件屬性時,就會返回該Carbon物件。

訪問器

其實上一節所說的日期時間的格式化,正是laravel模型訪問器的功能。專門用於在模型層面,修改模型屬性的展示方式。定義一個訪問器非常簡單,就是在模型內新增規範格式的方法函式。比如想要使用

$model->human_size

而資料庫沒有這個欄位,模型也沒有這個屬性,那麼使用訪問器好了,新增如下定義:

public funciton getHumanSizeAttribute(){}

方法內新增要處理的邏輯,並返回相應的值即可。使用 ->human_size 屬性訪問,就相當於訪問了該方法。

下面是一個相對複雜的方法,根據不同情況返回欄位name的值:

img

如果在忽略列表,就使用純小寫字母,如果不是忽略列表的元素,首字母大寫。最後組裝為空格間隔的字串返回。

在程式內使用 ->name 訪問的時候,就會呼叫該方法。我們仍然使用 tinker 進行臨時測試:

namespace App;
$e = new Event;
$e->name = "let's learn a Little Laravel together";
$e->Save();

這裡完成了模型的建立和屬性賦值,並寫入資料庫。save方法會返回一個 Events 模型物件,直接訪問其方法:

$e->name
// 輸出 "Let's Learn a Little Laravel Together"

正是我們定義的訪問器的修改策略。

對於已存在的欄位屬性,建立一些常用的訪問器方法能提高效率,比如知道使用者的姓氏和名字,我們可以返回其全名,模型內建立如下方法:

class User extends Model {
public function getFullnameAttribute()
{
    return $this->first_name . " " . $this->last_name;
}
}

宣告完成時候,在程式碼內使用:

$user = User::find(12);
echo $user->fullname;

雖然沒有fullname屬性,可是通過訪問器我們獲得了類似的能力。這是laravel提供的語法糖,很好使!

寫在最後

本文通過日期時間欄位的格式化方法,引申出laravel模型的訪問器功能,並通過例項介紹了具體的用法。

訪問器雖然好用,看上去像是模型的方法,實際上卻是呼叫了訪問器方法。書寫起來很簡潔,但是對於維護者要排查為數眾多的訪問器,並且沒有IDE的自動跳轉,這著實很考驗開發者的功底!

Happy coding :-)

我是@程式設計師小助手,專注程式設計知識,圈子動態的IT領域原創作者

本作品採用《CC 協議》,轉載必須註明作者和本文連結
write-less-do-more-make-you-out-of-door

相關文章