PHP Attribute Laravel開發環境應用集
前言
php8.0以後引入了Attribute的寫法,也就是我們可以在class的頭上或者function的頭上用
1 |
#[......] |
的方式來描述其他的可讀元素,本次將說明我們將Attribute運用在以下幾個地方
1.用於描述Controller中Request參數的內容
2.用於取有特定的Tag的Function來執行
3.用於Emun的其他描述
用於Request的參數描述
首先,我們現在app/Attributes/APITag.php 中描述以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php namespace app\Attributes; use Attribute; #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] class APITag { public function __construct( protected string $name, protected string $type, protected bool $required, protected string $description, ) { } } |
在這個Class中,我們定義它是用在Method上,而且可以重複
並且賦予他四個欄位,分別描述名稱、類型、必填以及說明,這四個欄位正是我們controller傳入值所需要描述的部分
接著在Controller中就可以這樣子定義參數
1 2 3 4 5 6 7 8 |
class APIController extends Controller { #[APITag(name:'id_number',type: 'string',required: true,description: '統一編號')] #[APITag(name:'name',type: 'string',required: true,description: '公司名字')] public function company_verify(Request $request): bool { } } |
假設這個Method要做的是情就是驗正公司的統編正確性,因此傳入值就會是統編與公司名字兩者
我們可以分別去描述每個參數的欄位名稱、型態、是否必填以及中文說明,當有多個參數的時候就堆疊多條就行了
那麼後續除了開發人員清楚知道參數規範之外,也可以透過ReflectionMethod或ReflectionClass來讀取
可以詳見後續描述[還沒寫到那….]
用於取特定的Tag值來執行
首先我們一樣在app/Attributes/InitTag.php 中描述以下
1 2 3 4 5 6 7 8 |
<?php namespace app\Attributes; use Attribute; #[\Attribute(\Attribute::TARGET_METHOD)] class InitTag {} |
因為這個案例是只要有放Tag就取出,因此我們沒有定義Attribute需要的內容,單純給上class name
接著在專案中任何一個class method加上這個Attribute,如下
1 2 3 4 |
#[InitTag] protected function init_start(): static { } |
應用的方式也相同,可以透過ReflectionMethod取得後透過動態呼叫來執行這些Method
用於Enum的其他描述
php8.1中提供了Enum方法,簡單來說是可以讓我們明確定義出固定某些參數與儲存於資料庫中的數值對應
舉例來說,我需要將客戶分類為 1: 有合作過的客戶,2: 沒有合作過的客戶
那麼這些中文字也很有可能被前端拿來做畫面渲染使用,因此我們不讓前端工程師獨立管理這些文字避免混淆可以像以下這樣做
首先,一樣在app/Attributes/Description.php 中描述以下
1 2 3 4 5 6 7 |
namespace app\Attributes; #[\Attribute] class Description { public function __construct(...$params){} } |
這次我們用更彈性的作法,直解把…$params傳入,就可以愛寫多少參數就寫多少
接著在app/Enums/Customer.php 來定義客戶的分類
1 2 3 4 5 6 7 8 9 10 |
namespace App\Enums; enum Customer: int { #[Description(name: '沒合作過')] case No = 2; #[Description(name: '有合作過')] case Yes = 1; } |
這樣子除了原始碼中可以清楚描述客戶的狀態外,也可以透過API一樣用ReflectionMethod來取得客戶該有的狀態中文字以及對應數值提供給前端使用
讓我們淋漓盡致的使用Attribute吧