原本有時數據庫中會使用enum()
來取代 數字 tinyint
,這樣更加明顯直觀
enum('low', 'medium', 'high')
不過我比較追求更高效率,以及希望數據庫更小
下面假設用一個 Invoice Model 來分享
以往會在config目錄建立
//config/common.php
<?php
return [
'invoice_status' => [
0 => '待批',
1 => '已批',
2 => '未付',
3 => '已付',
],
]
//Blade使用
{{ config('common.invoice_status_label')[$data->status] }}
但每次明明是改Invoice
的內容,但要去config
?
後來發現原來可以這樣做...
為每個Model建立自己的Enums
1. 建立app/Enums/Invoice/Status.php
<?php
namespace App\Enums\Invoice;
enum Status: string
{
case Pending = '0'; //待批
case Approved = '1'; //待寄
case Unpaid = '2'; //未付
case Paid = '3'; //已付
public function text(): string
{
return match($this) {
self::Pending => '待批',
self::Approved => '待寄',
self::Unpaid => '未付',
self::Paid => '已付',
};
}
public function color(): string
{
return match($this) {
self::Pending => 'bg-warning',
self::Approved => 'bg-primary',
self::Unpaid => 'bg-danger',
self::Paid => 'bg-success',
};
}
public function label(): string
{
return match($this) {
self::Pending => '<span class="badge badge-warning align-middle">待批</span>',
self::Approved => '<span class="badge badge-warning align-middle">已批待寄</span>',
self::Unpaid => '<span class="badge badge-danger align-middle">未付</span>',
self::Paid => '<span class="badge badge-success align-middle">已付</span>',
};
}
}
當然這邊的Pending、Approved 你改為 Status1, Status2 等等也是可以的
上面我分享了比較完整的Enums
一般大部分人你可以只保留 text()
就可以
2. 前往 Model 文件修改
use App\Enums\Invoice\Status;
protected $casts = [
'status' => Status::class,
];
3. balde顯示
//直接顯示
{{$data->status->text()}}
//用路徑直接Foreach
<select>
@foreach(\App\Enums\Invoice\Status::cases() as $item)
<option value="{{$item->value}}">{{ $item->text() }}</option>
@endforeach
</select>
4. 注意 & 方法2
上面之前這方法是把 $data->status
數一個純數字變成一個 object
, 所以你頁面中如果有類似 @if($data->status==1) checked @endif
等判斷會完全失效,如果你想要取獲原本的數值,應該用 $data->status->value
如果你是新開發的系統或者小型系統,修改起來不太難
如果你不喜歡影響原本的$data->status
而產生一個新的物件,不希望大量去改原有系統的,只你想升級優化代碼結果,你可以不用$casts,而自己建立一個function
,Model 中改成這樣
protected $enums = [
'status' => Status::class,
];
public function __get($key)
{
if (str_ends_with($key, '_enum')) {
$field = str_replace('_enum', '', $key);
if (isset($this->enums[$field])) {
return $this->enums[$field]::from($this->attributes[$field]);
}
}
return parent::__get($key);
}
這個改法,那麼你blade要這樣用
//顯示文字
{{$data->status_enum->text()}}
//顯示值
{{$data->status}}