讓我們提早發現語法錯誤

PHP 不需編譯,只要存檔就可執行,優點是很方便,缺點是很多程式語法上的錯誤必須在瀏覽器執行才能發現。PhpStorm 的 Code Inspection 就相當於編譯器,在程式開發階段就可檢查語法上的錯誤,再搭配單元測試檢查邏輯上的錯誤,如此雙重保障,就能提早發現錯誤加以解決,降低除錯成本。

Version


PHP 7.0.8
Laravel 5.2.41
PhpStorm 2016.2

實際案例


初學者在使用 PhpStorm 時,第一個不習慣的就是原來在 Sublime Text 很漂亮的程式碼,在 PhpStorm 打開了以後,平白無故多了很多警告,覺得很礙眼。

Authenticate.php1 1GitHub Commit : 將 Authenticate.php 改成 use Auth

與 Sublime Text 不同的是 :

  • 右上角多了 咖啡色 的方塊 : 表示 Code Inspection 偵測到錯誤。
  • scroll bar 多了 咖啡色 區塊 : 表示錯誤所在的相對位置。
  • Auth::guard()多了反白警告 : 表示錯誤所在的實際位置。

右上角方塊的顏色,表示各種不同的嚴重層級。

將滑鼠 hover 到 scroll bar 的顏色區塊上,會顯示錯誤訊息。

可用滑鼠直接點 scroll bar 的顏色區塊,快速跳到有錯誤的程式碼位置,或按熱鍵 F2 前進搜尋錯誤,⇧ + F2 倒退搜尋錯誤。

將滑鼠游標放放到反白的 Auth::guard() 上,PhpStorm 顯示 Method guard not found

主要是因為 Auth 為 Facade,執行上沒有問題,但是 Code Inspection 找不到。

將 namespace 引用改成 IDE Helper 所提供的 Auth 後,Code Inspection 就可以找到 Auth::guard() 了,右上角會出現 綠色 勾勾,表示通過 Code Inspection 檢查。2 2關於使用 IDE Helper 解決 Code Inspection 警告的問題,詳細請參考如何在 PhpStorm 活用 PHPDoc?

實務上對於 Laravel 或 package 的程式碼,我不會要求需通過 Code Inspection 檢查,但自己寫的程式碼,都必須通過 Code Inspection 的 綠色 勾勾。

調整 PhpStorm 檢查層級


若你覺得 Code Inspection 檢查太嚴格,希望 PhpStorm 只幫你檢查 PHP 語法就好,可以按右下角的哨兵符號,將 Code Inspection level 調到 Syntax

調整完 Code Inspection level 後,不用改 use Auth,也可以達到右上角會出現 綠色 勾勾。

實務上建議除非是 legacy code 真的不容易修正,否則不建議修改 Code Inspection level,畢竟 PhpStorm 所有的檢查都是有意義的,可以讓你及早發現淺在錯誤,避免實際在瀏覽器測試才發現錯誤的窘境。

設定 Code Inspection


PhpStorm -> Preferences -> Editor -> Inspections

假如你不想調整 Code Inspection level,只想將某個你認為不重要的警告拿掉,或降低層級,可以在 PhpStorm 的 preferences 設定。

如之前 Auth::guard() 的錯誤,你也可以直接在讓 undefined method 不要被檢查。

Code Inspection 所有的檢查規則都可以客製化,可以依照你的需求加以設定。

常見 Code Inspection


使用未定義變數

PostService.php3 3GitHub Commit : 使用未定義變數

直接使用一個未定義參數,Code Inspection 會加以警告。

Namespace 不存在

PostService.php4 4GitHub Commit : Namespace 不存在

Namespace 因為打錯,而引用了一個不存在的 namespace,Code Inspection 會加以警告。

Class 不存在

PostService.php5 5GitHub Commit : Class 不存在

依賴注入時 class 名稱打錯,注入了一個不存在的 class,Code Inspection 會加以警告。

Field 不存在

PostIDPO.php6 6GitHub Commit : 重構成 Parameter Object

將原 showTitle()$id$default 透過重構的 Introduce to Parameter Object 重構成 PostIDPO class。

PostService.php7 7GitHub Commit : Field 不存在

showTitle() 改傳入 PostIDPO 物件。

若將 id 打錯成 ip,使用了一個不存在的 field,Code Inspection 會加以警告。

Method 不存在

PostService.php8 8GitHub Commit : Method 不存在

若將 method 名稱打錯,呼叫一個物件不存在的 method,Code Inspection 會加以警告。

參數型別檢查

PostService.php9 9GitHub Commit : 新增 PostService

showTitle() 的參數與回傳值都使用了 PHP 7 的 scalar type hint。

PostServiceTest.php10 10GitHub Commit : 新增 PostServiceTest

若加上了 declare(strict_type = 1);,只要傳入的參數型別不對,Code Inspection 會提出警告。

Case 忘了加 break

PostService.php11 11GitHub Commit : Case 忘了加上 break

PHP 語法上允許 switch case 不加上 break 的寫法,但大多時候是忘了加上 break,而造成邏輯上的錯誤,Code Inspection 會提出警告,可是需求決定是否該加上 break

沒有 PHPDoc

PhpStorm -> Preferences -> Editor -> Inspections -> PHPDoc

PhpStorm 預設並沒有將 Missing PHPDoc comment 打勾,但實務上建議將此選項打勾。

PHP 7 因為有完整 type hint 與 return type,所以 PHPDoc 重要性不如以往,但 PHP 7 之前,則必須靠 PHPDoc 描述型別,PhpStorm 的 Code Inspection 才能發揮威力,所以建議開啟。

showTitle() 沒有寫 PHPDoc,Code Inspection 會提出警告。

要補上 PHPDoc 也很簡單,將滑鼠游標放在 method 名稱上,按熱鍵 ⌥ + ↩,選擇 Generate PHPDoc CommentGenerate PHPDoc for function 皆可。

PostService.php12 12GitHub Commit : 加上 PHPDoc

PhpStorm 會自動幫你加上 PHPDoc,只要再加上 method 功能的描述即可。

執行 Code Inpection


預設每個開啟的檔案都會自動執行 Code Inspection,此外你也可以自行選擇檔案,讓 Code Inspection 一次檢查多個檔案。

一次檢查多個檔案

在 project windows 用 ⌘ 與滑鼠選擇多個檔案,按滑鼠右鍵,選擇 Inspect Code...

選擇 Selected files

Code Inspection 最後會顯示有哪些檔案違反了哪些檢查規則。

一次檢查整個專案

Code -> Inspect Code…

選擇 Whole project

Code Inspection 將整個專案做檢查,會檢查出很多警告與錯誤,可視需求決定是否該修正。

Conclusion


  • 為了使 Code Inspection 沒有出現任何警告,可能會對程式碼產生強迫症,不過提早發現淺在錯誤總是好事,可視自己需求決定是否修正,或者關閉 Code Inspection 某個檢查規則。

Sample Code


完整的範例可以在我的 GitHub 上找到。

Reference


PhpStorm Online Help, Code Inspection

2016-07-24