iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0

利用 AI 幫我們寫了許多程式,今天來介紹一下 PHP 8 引入的 attribute,以及在 Laravel 內怎麼使用。

什麼是 attribute

PHP attribute,或者翻譯成屬性/注解,是 PHP 8 引入的新語法,讓開發者可以在 PHP 程式內,不管是類別、方法、屬性、參數或者常數等元素,加上額外的描述資訊(metadata)。

在其他的程式語言內,對應 Java 的 Annotation 或 C# 的 Attribute。

#[Attribute]
class Service {
    public function __construct(
        #[Attribute] public string $path
    ) {}
}

利用這個特性,過去一些必須要透過程式標記才能達成的效果,可以很直觀的在對應的位置加上 attribute 就能達成。

我們來看幾個例子。

Collection

當我們使用 Eloquent ORM,取出的資料超過一筆時,通常會取出一個 Illuminate\Database\Eloquent\Collection 物件

use App\Models\User;
 
$users = User::where('active', 1)->get();
 
foreach ($users as $user) {
    echo $user->name;
}

如果我們想要自定義 Collection,來加上我們自己的邏輯,可以這樣做

use Illuminate\Database\Eloquent\Collection;

class OrderCollection extends Collection
{
    public function unpaid()
    {
        return $this->filter(fn ($order) => !$order->isPaid());
    }

    public function totalRevenue()
    {
        return $this->sum(fn ($order) => $order->amount);
    }
}

要將自定義的 Collection 和 Model 綁定,我們可以在 Model 內宣告一段程式

或者更簡單的,直接加上 CollectedBy 這個屬性

namespace App\Models;
 
use App\Support\OrderCollection;
use Illuminate\Database\Eloquent\Attributes\CollectedBy;
use Illuminate\Database\Eloquent\Model;
 
#[CollectedBy(OrderCollection::class)]
class Order extends Model
{
    // ...
}

Observer

有時候我們會希望在 Model 改變時同步一些行為,比方說一旦某用戶被刪除了,我們就在後台新增一筆用戶刪除資料。

這類行為可以使用 Observer 達成

<?php
 
namespace App\Observers;
 
use App\Models\User;
use Illuminate\Support\Facades\Log;
 
class UserObserver
{
    /**
     * Handle the User "deleted" event.
     */
    public function deleted(User $user): void
    {
        Log::info("User deleted: {$user->id}");
    }
}

要將 Observer 和 Model 綁定,我們可以在 Service Provider 內註冊,或者使用更直觀的 ObservedBy

use App\Observers\UserObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
 
#[ObservedBy([UserObserver::class])]
class User extends Authenticatable
{
    // ...
}

這樣,當我們未來在除錯時,就不需要從 Service Provider 內找哪邊產生這個更動的邏輯,只要從 ORM 上面的 attribute 就可以找到了。

當然 Laravel 內使用到 attribute 的地方還有很多,這邊只是簡單的介紹兩種,希望未來大家對這個寫法更加熟悉,未來遇到相似邏輯時可以想到或許存在這樣的寫法。

今天的部分就到這邊,我們明天見!


上一篇
Day 06:用 Livewire 撰寫前端互動元件
系列文
Laravel 12 開發者幸福度升級指南7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言