如何使用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。