目錄
- 介紹
- 代碼規范檢查與修復
- 在git commit時自動檢查代碼規范
- 后記
介紹
在團隊協作開發中,代碼規范是必要的。以前的規范都是自己定,然后手動檢查,很難做到有效的約束。
現代的PHP,則有得到廣泛認可的編碼規范:PSR-1
,PSR-2
。
同時也有配套的包squizlabs/php_codesniffer
(下面簡稱phpcs)可以自動檢查代碼是否符合規范,並能自動修復部分不規范的代碼。
結合brainmaestro/composer-git-hooks
,可以進一步做到,在git commit
時,強制代碼規范的檢查。
代碼規范檢查與修復
安裝phpcs
包:
composer require squizlabs/php_codesniffer --dev
這個包,包含了2個工具:
- phpcs用於檢查代碼規范;
- phpcbf用於根據代碼規范修復代碼。
工具位於vendor/bin/
目錄。
假設要檢查app/
目錄下的代碼是否符合規范,執行:
$vendor/bin/phpcs --standard=PSR1,PSR2 app/ routes/ config/
其中,--standard
用於指定檢查規范時使用的標准,這里使用PSR1和PSR2。而app/,routes/和config/是laravel工程的代碼目錄。
手動修復代碼規范是一件很累人的事情,一般是先通過自動修復,對於修復不成功的再手動修復。執行以下命令可以完成自動修復。
$vendor/bin/phpcbf --standard=PSR1,PSR2 app/ routes/ config/
有些規則,phpcbf
無法自動修復,而我們改起來又十分煩瑣,可以考慮自定義這些規則。比如上面截圖中的一行不能超過120個字符的這條規則,無法被自動修復,但不論是第三方包,還是我們自己寫的代碼(通常是注釋),超過120個字符的非常多,一一修復就太累了。於是修改了該條規則,將數值擴大到240。
具體方法是創建ruleset.xml文件,拷貝以下內容
<?xml version="1.0"?>
<ruleset name="Custom">
<description>Zend, but without linelength check.</description>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="240"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>
</ruleset>
然后在執行代碼檢查時,在--standard
參數附上自定義規則文件路徑
$vendor/bin/phpcs --standard=PSR1,PSR2,./ruleset.xml app/ routes/ config/
每次要敲這么長的命令並不方便,一般是寫在composer.json
中,通過composer lint
執行代碼檢查,通過composer lint-fix
修復代碼。
要實現這樣的效果,修改composer.json
, 在scripts增加:
"scripts": {
// 省略其他部分...
"lint": "phpcs --standard=PSR1,PSR2,./ruleset.xml app/ routes/ config/ ",
"lint-fix": "phpcbf --standard=PSR1,PSR2 app/ routes/ config/ "
}
然后執行composer lint
和composer lint-fix
試試。
在git commit時自動檢查代碼規范
在上一節中,我們已經支持代碼規范檢查和代碼修復。但是實際開發中,常常會忘記要去檢查。為了更好的管控流程,最好能在git commit時自動檢查,如果不符合規范就停止commit。這就需要使用git的hooks機制,在pre-commit時,執行規范檢查和代碼修復 。可以直接編輯 .git/hooks/pre-commit
,寫入在每次git commit之前要執行的腳本。
也可以通過brainmaestro/composer-git-hooks
這個包解決此問題,這里使用后面這個方案。
首先安裝包:
$composer require brainmaestro/composer-git-hooks
然后編輯composer.json,在extra增加:
"extra": {
// 省略其他部分...
"hooks": {
"pre-commit": [
"echo committing as $(git config user.name)",
"composer run lint"
]
}
},
寫好腳本以后還不能直接使用,需要先通過vendor/bin/cghooks
生成.git/hooks/pre-commit
。
$vendor/bin/cghooks add # 將創建.git/hooks/pre-commit
或者
$vendor/bin/cghooks update ## 將composer.json的內容更新到.git/hooks/pre-commit
如果composer.json與.git不是在同一個目錄下,還需要加--git-dir參數,比如
vendor/bin/cghooks add --git-dir="../.git"
生成.git/hooks/pre-commit
以后,就可以試試,修改一些文件,然后執行git commit看看git hooks有沒有被觸發。類似下面的執行結果。然后如果有執行錯誤,會發現git commit
不成功。
至此,代碼規范的檢查就大功告成了。
后記
- 其實就是將
nodejs
的eslint
,husky
對應到php
版本(沒有prettier
)。 - 有些工程,前端代碼和后端代碼放在同一個git工程下的不同目錄,js那邊使用husky自動生成
pre-commit
鈎子,而laravel這邊使用了brainmaestro/composer-git-hooks
鈎子生成了pre-commit
,會出現相互覆蓋的問題。解決此問題的方法是有2種:一種是創建一個scripts/pre-commit
,讓開發者在clone
工程以后,拷貝到.git/hooks/pre-commit
;另一種就是在工程根目錄下安裝husky
,然后在將工程中所有commit
之前要做的檢查都寫入進來。推薦使用第2種方法,husky
這個包做得比php這邊的包要好用。