如何在 PhpStorm 使用 Code Generation?
實務上開發專案時,有一些程式碼會不斷的出現,這時可靠 PhpStorm 的 Code Generation 幫我們產生這些 code snippet,除此之外,我們也可以將自己的 code snippet 加入 Live Template,可加快發開速度,並減少 typo。
Version
PHP 7.0.8
Laravel 5.2.41
PhpStorm 2016.2
Namespace
Laravel 5 的 app 目錄下都遵循 PSR-4,也就是每個在 app 目錄下的 class 都要有 namespace,且 Laravel 與 package 都有自己的 namespace,實務上我們不可能記得了這麼長的 namespace,Code Generation 可以幫我們自動引入相對應的 namespace,若 namespace 名稱相同,會讓我們用選的。

return type 為 Collection,這是 Laravel 擴充的型別,輸入 Col 之後,Code Completion 會顯示 Collection,後面為其完整的 namespace。

Code Generation 自動幫我們 use 了正確的 namespace,不用我們操心。

Post 出現反白,Code Inspection 抱怨找不到 Post class。

將滑鼠游標放在反白的 Post 上,按熱鍵 ⌥ + ↩,選擇 Import class。
PostRepository.php1 1GitHub Commit : PostRepository 自動 use namespace
Code Generation 自動幫我們 use 了 model 的 namespace,不用我們操心。

實務上我們常常只會維護程式碼,但不會去維護 namespace,造成沒用到的 namespace 越來越多。
如我們將 return Post::all() 刪除後,因為沒使用到 Post,所以在 PhpStorm 的 use App\Post 會反灰警告你此 namspace 目前沒人使用。
PostRepository.php2 2GitHub Commit : PostRepository 自動刪除沒用的 namespace
按熱鍵 ⌃ + ⌥ + O,PhpStorm 會自動幫你將沒用到的 namespace 刪除。
Constructor
使用依賴注入後,必須建立 constructor 並注入相依物件,在每天的開發過程中需要不斷發生,Code Generation 可以幫我們自動完成 constructor injection。

按熱鍵 ⌃ + N,出現 Generate 選單,選擇 Constructor...。

在 constructor 參數列輸入要依賴注入的 class 名稱,輸入前幾個字母即可,Code Completion 會啟動讓你挑選 class 名稱。

Code Generation 自動幫我們 use 了 PostRepository 的 namespace。
輸入 $,Code Completion 會自動顯示建議的參數名稱,選擇你喜歡的命名方式。

Code Inspection 會出現警告,因為還沒產生 constructor 的 PHPDoc。

按熱鍵 ⌥ + ↩,選擇 Update PHPDoc Comment,由 PhpStorm 來幫我們產生 PHPDoc。

PhpStorm 自動幫我們產生 PHPDoc。

繼續按熱鍵 ⌥ + ↩,選擇 Initialize fields,由 PhpStorm 來幫我們產生其他程式碼。

選擇要由 Code Generation 要產生 field 的程式碼。
PostService.php3 3GitHub Commit : 新增 PostService
Code Generation 一氣呵成幫我們產生了 field,在 constructor 產生了指定 field 相對應的程式碼,另外也 use 相對應的 namespace。
Getter/Setter
實務上常常需要對 private field 加上 getter 與 setter,如重構的 Self Encapculate Field 也會用到,Code Generation 可以幫我們自動產生 getter 與 setter。

新建立一個 $postId field,按熱鍵 ⌥ + ↩,會出現各種 getter 與 setter 產生方式。
PostService.php4 4GitHub Commit : 支援 PHP 7 type hint 與 return type 的 getter 與 setter
若選擇 Add getter and setter,Code Generation 會幫我們自動產生支援 PHP 7 type hint 與 return type 的 getter 與 setter。
PostService.php5 5GitHub Commit : 支援 fluent setter
若選擇 Add fluent setter,Code Generation 甚至會幫我們自動產生 fluent 風格的 setter。
Implement Method
在物件導向中,實踐抽象化最重要的就是 interface,所以常常有 implement interface 的需求,Code Generation 提供兩種方式讓我們快速實作 interface。
SMSInterface.php6 6GitHub Commit : 新增 SMSInterface
定義了 SMSInterface,準備對簡訊的發送加以抽象化。

建立了 AzureSMSService,實作 SMSInterface,Code Inspection 馬上提出 尚未實作 SMSInterface 警告。

按熱鍵 ⌥ + ↩,選擇 Add method stubs。

Code Generation 會自動幫我們根據 interface 產生了 method 框架,連 PHPDoc 也會幫我們產生。

另外一種方式,按熱鍵 ⌃ + I,出現 Choose methods to implement 視窗,選擇你要 implement 的 method。
AzureSMSService.php7 7GitHub Commit : 自動實現 interface 的 method
Override Method
繼承是實現物件導向抽象化的另一種方式,當子類別可 override 父類別的 method。

AzurePostService 繼承了 PostService。

若我們想 override 父類別 PostService 的 showTitle(),可按熱鍵 ⌃ + O,出現 Choose method to override 視窗,選擇你要 override 的 method。
AzurePostService.php7 7GitHub Commit : 自動複寫 class 的 method
Code Generation 會自動幫我們根據父類別產生 method 框架,連 PHPDoc 也會幫我們產生。
Postfix Completion
很羨慕 fluent API 的好用嗎? Postfix Completion 讓我們可以類似 fluent API 的方式寫 PHP。
not

輸入 $title.not,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 ! 區塊。
par

輸入 $title.par,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 ( ) 區塊。
if

輸入 $title.if,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 if ( ) 區塊。
else

輸入 $title.else,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 if (! ) 區塊。
fe

輸入 $title.fe,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 foreach( ) 區塊。
null

輸入 $title.null,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 if ( === null) 區塊。
nn

輸入 $title.nn,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 if ( !== null) 區塊。
return

輸入 $title.return,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 return。
echo

輸入 $title.echo,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 echo $title;。
var_dump

輸入 $title.var_dump,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 var_dump()。

PhpStorm -> Preferences -> Editor -> General -> Postfix Completion
在 Preferences 設定底下,可以看到所有 PhpStorm 支援的 Postfix Completion,包含 JavaScript 與 PHP。
可惜 Postfix Completion 無法擴充,就只能用 PhpStorm 所提供的 postfix。
Live Template
除了 Postfix Completion 外,PhpStorm 另外提供 Live Template,這是可以自行擴充的。
fore

輸入 fore,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 foreach( ) 區塊。
forek

輸入 forek,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 foreach( ) 區塊,並包含 key 與 value。
thr

輸入 thr,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 throw new 區塊。
prif

輸入 prif,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 private function 區塊。
prof

輸入 prof,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 protected function 區塊。
pubf

輸入 pubf,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 public function 區塊。

PhpStorm -> Preferences -> Editor -> Live Templates
在 Preferences 設定底下,可以看到所有 PhpStorm 支援的 Live Template,還包含各種其通語言,甚至包含 Angular 2。
自訂 Live Template
你也可以自己將常用的 code snippet,存成自己的 Live Template。

如在寫單元測試時,$this->assertEquals() 常常使用,所以我們想將它存成 Live Template。
選擇你的 code snippet,Tools-> Save as Live Template。

輸入你自己的想要的縮寫,並在滑鼠游標停止處加上 $END$,將來 PhpStorm 會將游標停在此方便你輸入。

輸入 pubf,按熱鍵 ⇥。

Code Generation 會自動幫我們產生 $this->assertEquals(),並將游標放在 ( ) 中,方便你後續輸入。
Conclusion
- Post Completion 無法自行擴充,不過 Live Template 可以自行擴充。
- Post Completion 與 Live Template 有些是重複的,可視需求決定用哪一種,只要能提高開發效率即可。
- 要善用工具改善開發速度,將時間花在真正需要的地方,Code Generation 讓我們可以打更少的字, 還可以避免 typo。
Sample Code
完整的範例可以在我的 GitHub 上找到。
Reference
PhpStorm Online Help, Generating Code
PhpStorm Online Help, Using Postfix Template
PhpStorm Online Help, Live Template