與上一篇 Yii 相關的文章類似,這篇文章也是整理了一些 PHP 的小筆記。由於這些內容較難各自形成完整的主題,因此統一開篇文章來記錄。
文字與變數的交織
在處理日誌(Log)或輸出資料時,我們經常會遇到長字串,其中夾雜著多個變數與條件判斷,例如:
- 在某些情況下,需要選擇不同的變數值。
- 在某些條件下,字串內容會動態變化。
建議使用 sprintf()
來組合字串,這樣可以避免 .
、?:
、()
交錯出現,提高可讀性。例如:
$message = sprintf("使用者 %s 在 %s 進行了 %s 操作", $username, $time, $action);
用 match 簡化判斷
match
是 PHP 8.0 新增的語法,我們可以利用它來簡化 if-elseif
的判斷,特別適用於條件簡單且處理邏輯單純的情境。例如:
$browser = match (true) {
str_contains($agent, "MSIE 8.0") => "Internet Explorer 8.0",
str_contains($agent, "MSIE 7.0") => "Internet Explorer 7.0",
str_contains($agent, "MSIE 6.0") => "Internet Explorer 6.0",
str_contains($agent, "Firefox/3") => "Firefox 3",
str_contains($agent, "Firefox/2") => "Firefox 2",
str_contains($agent, "Chrome") => "Google Chrome",
str_contains($agent, "Safari") => "Safari",
str_contains($agent, "Opera") => "Opera",
default => substr($agent, 0, 99),
};
可以看出,在 簡單的條件匹配 中,使用 match
使得代碼更加清晰、精簡。
API 參數模組化
在開發 API 時,我們可以將 request
當作一種 Model 來處理(類似資料表的概念),這樣就不需要每次都手動取得參數,例如:$this->content['name']
可以改為 $this->model->name
。
雖然兩者的差異看似不大,但這樣做有幾個好處:
- 方便後續依賴注入:可以直接用這個 Model 來連結其他資料表,減少重複的處理邏輯。
- 提升可讀性與維護性:對於其他開發者來說,可以直接查看 Model 來一次性確認所有輸入參數的名稱與類型,減少理解成本
資料庫鎖
在先前的文章資料庫系列 - 4: DB Lock中,我們曾經探討過資料庫鎖(DB Lock)。
在實際開發時,無論是新增、更新還是刪除資料時,都應該使用資料庫鎖來確保資料一致性(查詢時通常不需要)。即使當前系統的流量不大,似乎不需要鎖,但隨著業務增長,未來可能會遇到並發問題,這時候才補救就來不及了。
此外,要特別注意對同一張表的操作應使用相同的鎖,否則鎖的作用將會失效。例如:
$lockKey = "order_lock_" . $orderId;
輸出文件編碼
當我們輸出資料時(例如 Excel),經常會遇到編碼問題,導致中文顯示為亂碼。經過多種嘗試後,,我推薦一個最方便簡單的方式:
mb_convert_encoding($content, "UTF-8")
SQL 與高併發
當我們從資料庫查詢資料時,應該盡量將篩選條件或處理邏輯放入 SQL,讓查詢結果直接符合需求,而不是先取出所有資料後再進行分類或篩選。例如:
❌ 錯誤做法(先抓取所有資料,再用 PHP 過濾):
$allUsers = User::find()->all();
$activeUsers = array_filter($allUsers, fn($user) => $user->status === 'active');
✅ 正確做法(直接在 SQL 中篩選):
$activeUsers = User::find()->where(['status' => 'active'])->all();
這樣做有以下好處:
- 減少 PHP 的運算負擔,讓資料庫幫忙處理篩選,效能更佳。
- 降低高併發時的性能問題,避免一次取出過多不必要的資料,影響伺服器效能。