這個 PHP 系列將介紹我在工作中獲得的一些 PHP 相關小知識、曾經不小心踩過的雷,以及常見的誤解和錯誤概念,例如魔術方法、回呼函數(callback)、Composer 等。在這第一單元中,我們不會討論 PHP 的來源或歷史這些古板的內容,而是直接開始介紹一些實用的工具吧!
在產品的線上環境中,由於用量大、流量高,往往無法像在本地一樣進行測試和比較。不過,有些情境卻必須在線上環境才能重現,這時候就可以使用 xhprof 這個 PHP 分析器。它相對於其他工具消耗的 CPU 資源較少,但仍能提供重要的性能數據,幫助我們在鎖定問題時有更清晰的方向。
不過,唯一的缺點是,這個工具目前僅支援 PHP 7.4 版本以前的版本,後續版本將不再提供支持。
有時候,我們只是想快速測試一些東西,但又不想在目前的專案中騰出空間去做這件事情(例如切換分頁或更改 PHP 版本),這時候就可以使用 PHP 沙盒 這個網站。除了可以直接執行 PHP 程式碼外,還能選擇各個主版本以及子版本的 PHP,測試起來非常方便!
在編寫程式時,我們常常會進入心流狀態,程式碼如湧泉般源源不斷流出。當回過神來後,往往會發現雖然邏輯正確,但格式卻一團亂。這時候,PHP_CodeSniffer 就成了我們的好幫手!
下載這個套件後,只需執行一個指令,它就會檢查程式碼中的格式問題,並指出具體的錯誤所在。更棒的是,PHP_CodeSniffer 還能直接幫你修正格式問題,讓你的程式碼更整潔、更具可讀性!
由於 PHP 是弱型別語言,為了保持團隊的運作效率,通常會要求開發者撰寫註解,以便後續的同事能夠理解程式碼。其中一種常見的方式就是使用 PHPDoc。PHPDoc 是一種廣泛使用的非正式標準,提供了多種標記,例如 @param
、@return
和 @throws
等,以方便描述函數的參數、返回值及可能拋出的異常。
此外,PHPStan 內建的功能可以自動生成 PHPDoc 註解,進一步提高了編碼的效率與可讀性。
PHPStan 是一個用於靜態分析 PHP 程式碼的工具,可以透過調整規則等級決定檢測的層級[註1]。此外,它還支援使用正則表達式來忽略特定的錯誤。常見的報錯包括呼叫函數時的參數型別錯誤、註解錯誤(例如調整了參數卻未更新相應的註解)、以及無效的判斷式[註2]等。
範例設置檔:
parameters:
level: 2
paths:
- app
universalObjectCratesClasses:
- Illuminate\\Support\\HigherOrderCollectionProxy
ignoreErrors:
- '#Call to an undefined static method Illuminate\\\\Support\\\\Str::(mb_trim)\\(\\)#'
- '#Call to an undefined static method Illuminate\\\\Validation\\\\Rule::(mimetypes)\\(\\)#'
- '#Call to an undefined static method Corp104\\\\Vip\\\\Redis\\\\Facades\\\\RedisCache::(get|put|del|setex)\\(\\)#'
- '#Call to an undefined method Illuminate\\\\Http\\\\Request::(additionalInformation|csrInformation|createServerRequest)\\(\\)#'
- '#Call to an undefined method Illuminate\\\\Http\\\\UploadedFile::(overwrite|read)\\(\\)#'
- '#Call to an undefined method Illuminate\\\\Redis\\\\Connections\\\\Connection::(get|put|del|setex)\\(\\)#'
- '#Call to an undefined method Illuminate\\\\Support\\\\HigherOrderCollectionProxy::(\\w+)\\(\\)#'
- '#Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasOne::(\\w+)\\(\\)#'
- '#Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany::(\\w+)\\(\\)#'
[註1] 主要是為了避免檢測層級設置過高時,產生大量誤報,而這些誤報多來自 Laravel 提供的魔術方法。
[註2] 例如,判斷式 empty(collect())
必定會返回 false。