PHP 圈過去十年常被推薦的答案只有兩個——全端 Laravel、企業級 Symfony。本週這個問題終於有了第三個真正的選項,因為 Brent Roose 主導的 Tempest 框架在 2 月 12 日正式發布 3.0,並在不到兩個月內連續推出 3.0、3.1、3.2 三個 minor release。如果你還沒聽過 Tempest,一句話介紹:這是一個只支援 PHP 8.5 以上的現代化框架,把 attribute 當成路由與指令的第一公民,並且積極刪除其他框架還在要求你寫的樣板碼。
Tempest 3.x 系列裡,有三件事最值得 PHP 工程師注意。
一、只支援 PHP 8.5——因為框架本身就是圍繞新版 PHP 設計
Tempest 3.0 是第一個把最低 PHP 版本拉到 8.5 的主流框架。這聽起來很激進,但正是它能做出與眾不同設計的原因。PHP 8.5 帶來了管線運算子(pipe operator)、新的 array_first / array_last、persistent attribute,以及 enum 與 readonly class 的多項補強。Tempest 的 controller、console command 與 event handler 全部用 attribute 宣告,看起來幾乎像一套乾淨的 DSL,而這套 DSL 之所以能存在,是因為 PHP 8.5 終於把所有缺的拼圖補齊。
二、CSRF 防禦從 token 換成兩個 HTTP 標頭
這是我覺得從實戰安全角度最有趣的改動。傳統的 anti-CSRF token 設計(隱藏 form 欄位+middleware 對比 session)大家都熟,但它脆弱:AJAX 的 SPA 常常忘記帶、行動 App 寫死 token、最後每個團隊都會在某個路由加上「我這條請排除」的旗標。Tempest 3.0 直接拿掉了 <x-csrf /> 元素,改用瀏覽器自動送出的 Sec-Fetch-Site 與 Sec-Fetch-Mode 標頭。同源 POST 會帶 Sec-Fetch-Site: same-origin,被允許通過;跨站 CSRF 攻擊則自然會帶 same-site 或 cross-site,被擋下。這比起傳統 token,更貼近瀏覽器原生語意,也更難設定錯。
三、PHP 自動生成 TypeScript 介面
2 月 20 日 Tempest 釋出了一個工具,會掃描 domain 類別並輸出對應的 TypeScript interface。這聽起來很無聊,直到你花了半年盯著前後端 DTO 慢慢漂移開來。在 Tempest 裡,你改 PHP 類別、執行一行 console 指令,React / Vue / Svelte 端就拿到新的型別形狀。配合 3 月新增的 HasOneThrough、BelongsToMany ORM 關聯、view 的 source-map debug 與 UUID 主鍵,Tempest 與 Laravel 的實用功能差距正在被快速補齊。
對你來說的意義
如果你這一季要開新的 SaaS 或內容網站,團隊也適應 PHP 8.5,Tempest 已經是中小型專案的可生產選項。如果你維護的是 Laravel codebase,Tempest 不是「明天就換」,而是訊號。它在兩個地方做出的決定(attribute 為主的路由、Sec-Fetch-* 取代 CSRF token)夠好,好到大型框架接下來會跟進整合。
我的觀點
PHP 圈被「Laravel + 其他」的雙頭結構卡住很久,這也是為什麼這個語言對外人來說不像它應該的那麼有趣。Tempest 是我看過最具說服力的一次嘗試——把新版 PHP 當成真正的差異化武器,而不是 changelog 裡的一行勾選。其中 Sec-Fetch-* 的 CSRF 設計尤其值得抄:它更簡單、更難設定錯、也更貼近平台未來的方向。就算你最後沒有採用 Tempest,也應該把這個模式抄回去。
資料來源
- Tempest 3.0 — Tempest blog
- PHP Framework: Tempest 3.0 brings new error handler — Heise
- Tempest 3.0 release on GitHub
- Tempest blog index
- Cross-Site Request Forgery Prevention — OWASP Cheat Sheet