如何使用PHPDoc寫註解?
註解是一定要寫的,但要怎麼寫才能使開發者與工具都看得懂呢?PHPDoc是目前PHP註解的標準,提供了統一的註解寫法,並且獲得PhpStorm的支援,PHPUnit也使用PHPDoc,事實上Laravel的source code也是使用PHPDoc格式來寫註解。
Version
PhpStorm 10.0.1
為什麼要寫註解?
使用人話解釋
使用人話描述顯示邏輯、商業邏輯與資料庫邏輯,避免日後需求改變須維護時,自己或其他人看不懂而無法維護。讓 IDE得知型別
PHP是弱型別語言,可以使用type hint,也可使用duck type,當使用duck type時,只有在run time才能得知型別,IDE無法從design time得知型別,因此無法實現code complete與inspection,必須依賴PHPDoc描述型別,這也是PHP比其他語言都更依賴註解的原因。
如何建立PHPDoc?
在PhpStorm輸入
/**,然後按下↩,PhpStorm會自動依據當時的游標的位置產生適當的PHPDoc blocks。Code->Generate或按⌘ + N,會產生
Generate選單,選擇PHPDoc Blocks。
在
適當時機按下⌥ + ↩,會出現Generate PHPDoc for ...。如剛建立完class, property或method時。
檔頭註解
使用⌘ + N建立PHP Class時,PhpStorm預設會在檔頭插入檔頭註解。1 1PhpStorm預設的檔頭註解並非如此,詳細請參考如何修改PhpStorm的檔頭註解?
1 | Post model的repository |
第1行使用中文敘述整個檔案(整個class)的功能。2 2不建議使用英文寫註解,因為註解主要是給人看的,易懂是其目的,因為每個人對英文的理解程度不一樣,若因此而造成對註解的誤解,就失去寫註解的意義了。
之後會空一行。
@version
1 | @version 0.1.0 |
目前程式的版本,一開始為0.1.0。建議採用Major.Minor.Patch的版本命名方式,也就是Breaks.Features.Fixes。3 3詳細請參考Sematic Versioning
@author
1 | @author oomusou [email protected] |
程式一開始建立的原作者。第1個參數為姓名,第2個參數為email。
@date
1 | @date 11/22/15 |
程式一開始建立的日期。
@since
1 | @since 0.1.0 11/22/15 oomusou: 新增getLatest3Posts() |
程式的改版紀錄。第1個參數為版本號,第2個參數為修改日期,第3個參數為修改者名稱,後見加上:,再加上簡易註解。
若有很多版本,就繼續加上多個@since。
Class註解
使用⌘ + N建立PHP Class時,PhpStorm自動會在class之前插入class註解。4 4interface與trait註解寫法比照class。
1 | Class PostRepository |
第1行PhpStorm預設使用Class加上class名稱當註解,由於one class per file原則,所以class的註解就相當於檔案的註解,因此不用再特別敘述。
之後會空一行。
@package
1 | @package App\Repositories |
描述class所屬的namespace,PhpStorm會自動建立。5 5建議每個class都要依據PSR-4的建議使用namespace,詳細請參考如何使用Namespace?
@method
1 | namespace Illuminate\Support; |
平常不會使用,除非使用__call()或__callStatic() 動態產生method,由於這種寫法PhpStorm的auto complete抓不到,因次要使用PHPDoc特別描述。6 6在Laravel最典型就是schema builder的unique()與nullable(),在Fluent class內是由__call()動態產生,需另外使用PHPDoc的@method加以描述,PhpStorm才可以抓的到。
@property
1 | /** |
平常不會使用,除非使用__get()與__set() 動態產生 property,由於這種寫法PhpStorm的auto complete抓不到,因此要使用PHPDoc特別描述。7 7在Laravel最典型的就是model的欄位,是使用__get()與__set()動態產生property,需使用IDE Helper產生_ide_helper.php,裡面就是用@property描述,PhpStorm才可以抓的到model的欄位。
Property註解
當建立property時,在property上方輸入/** + ↩,PhpStorm會自動產生property的註解。
@var
1 | @var Post 注入的post model |
對每個property做註解。
第1個參數為property的型別,由於PHP允許duck type,這會導致PhpStorm的auto complete無法執行,所以一定要要輸入型別。
第2個參數為property的註解,使用中文描述該property的意義。
Method註解
當使用
pubf自行建立method時,在method名稱後面按 ⌥ + ↩,PhpStorm會自動根據參數建立method的PHPDoc blocks。當使用⌃ + I實踐interface的method時,只要interface有寫好註解,只要在Add PHPDoc選擇
Copy from base class,就可以將interface所寫好的註解複製過來。

1 | 回傳最新3筆文章 |
第1行使用中文敘述整個method的功能。8 8interface與trait內的method註解寫法,比照class的method。
之後會空一行。
@param
1 | @param string $field 排序欄位 |
對method的每個參數做註解。
第1個參數為傳入參數的型別。
第2個參數為傳入參數的變數。
第3個參數為傳入參數的敘述。
@return
1 | @return Collection 最新3筆文章 |
對method的回傳值做註解。
第1個參數為回傳值的型別。
第2個參數為回傳值的敘述。
由於PHP允許duck type,因此method的參數可以不寫型別,但這樣使得PhpStorm無法在design time得知該參數的型別,因此auto complete與inspection無法執行,所以建議在PHPDoc block一定要加上@param描述參數型別,@return描述回傳型別。此外,若參數為物件,也建議加上class或interface的type hint,一來PhpStorm的auto complete與inspection可以抓到,二來在unit test時,可以使用service container的dependency injection,詳細請參考如何測試內含相依物件的函式?。
@throws
1 | @throws InvalidArgumentException 若提供的參數不是array型別 |
若method有使用exception,可使用@throws描述。
第1個參數為exception的型別。
第2個參數為該exception的敘述。
@todo
1 | @todo 此段程式碼尚未重構,建議有時間時加以重構 |
若method尚有功能未完成,可寫在@todo裡。
@since
若之後該method因bug或需求變更而需要維護,使用@since描述其變更,與擋頭註解的@since寫法一樣。
@deprecated
若該API或public method即將在未來版本停用,可加上@depricated,後面加上註解,PhpStorm對於@depricated有特別的支援。

只要使用該API的method,都會加上刪除線提醒。

Method內註解
當PhpStorm無法得知該變數的型別,而導致auto complete與inspection無法執行時,就必須自行使用@var去描述該變數的型別。
@var
最典型的用法是Laravel的Eloquent傳回一個物件,但我們知道他本質上是某個型別的model,但PhpStorm並不知道,因此我們必須自行使用@var加以描述。
PHPUnit註解
PHPUnit也對PHPDoc做了一些擴充,在此僅對最常用的tag加以介紹。
@test
PHPUnit預設會以test開頭的method視為test method,若你不想遵循這個規則,則在method的註解加上@test也可以。
@group
你可以將test method加以分組,將來PHPUnit只測試該group即可。9 9若使用PhpStorm執行PHPUnit,按⌃ + ⇧ + R可對單一method做測試,詳細請參考如何使用PhpStorm測試與除錯?1
oomusou@mac:~/MyProject$ php vendor/bin/phpunit --group=PostRepository0
@expectedException
若你要測試的就是該method產生exception,PHPUnit並沒有提供對應的assertion,須在test method的註解的方式加上@expectedException,後面加上預期的exception類別。
Conclusion
- 建議使用
中文寫註解,避免因為每個人對於英文的理解不一樣,而造成誤解。 - 其他程式語言沒有依照一定的格式寫註解,或許問題沒那麼大,但因為PHP為
弱型別語言,為了讓IDE能支援auto complete與inspection,使用標準的PHPDoc格式非常重要。 - PHPDoc不僅僅只有在PhpStorm可用,其他如Sublime Text,Eclipse與Netbeans也都支援PHPDoc。