筆者在6月份加入新團隊,新團隊這邊剛組建起來,基礎一些東西還處於待完善狀態,好比筆者組內同窗約定使用PSR-2的編碼風格規範,可是並非全部人都嚴格按照PSR-2來提交代碼。php
最大的緣由就是口頭的約束力極爲有限,而團隊中你們使用的編輯器不統一,有使用phpstorm,也有使用VS Code更有vim,而各類編輯器都有本身的格式化規則,所以代碼風格統一是個問題;git
具體一點來講,當張三使用VS Code提交了一個代碼文件,李四pull代碼以後使用phpstorm進行格式化後再提交,代碼風格發生變化提交到服務器,張三再pull代碼,使用VS Code格式化,代碼又一次發生變化;這樣反反覆覆的改變,開發同窗會以爲麻煩,代碼審計同窗也一樣麻煩;
在筆者上家公司的技術團隊,會由架構組來處理相似的問題,因而這裏筆者把上一個團隊實現的方式照搬過來,一樣在git的鉤子上作文章,若是有人的代碼不符合psr-2代碼風格規範,經過git鉤子將不其commit,而且給出具體行號和具體的緣由,更方便的是提供一個快速格式化的命令。vim
php-cs能夠用來檢測代碼是否符合PSR-2規範,同時支持對不符合規範的代碼自動格式化,讓其轉成PSR-2的編碼風格。服務器
php-cs依賴於composer,因此筆者須要先安裝composer,安裝的方法有不少種,這裏提供mac操做系統下兩種安裝方法微信
brew安裝composer命令爲:架構
brew install composer
手動安裝composer命令爲:composer
wget https://getcomposer.org/download/1.7.1/composer.phar && chmod 777 composer.phar && mv composer.phar /usr/local/bin/composer
安裝好composer以後,能夠用composer快速安裝php-cs,安裝命令以下phpstorm
composer global require "squizlabs/php_codesniffer=*"
當命令執行完成以後,會在筆者當前用戶的主目錄下建立一個 .composer 目錄,在目錄中包含了筆者須要的php-cs,此時筆者能夠執行下方命令來驗證是否安裝成功編輯器
~/.composer/vendor/bin/phpcs --help
當命令執行後,若是能看到下方的一些信息,那麼就表明安裝成功ide
- Check STDIN instead of local files and directories -n Do not print warnings (shortcut for --warning-severity=0) -w Print both warnings and errors (this is the default) -l Local directory only, no recursion -s Show sniff codes in all reports -a Run interactively -e Explain a standard by showing the sniffs it includes -p Show progress of the run -q Quiet mode; disables progress and verbose output -m Stop error messages from being recorded (saves a lot of memory, but stops many reports from being used) -v Print processed files -vv Print ruleset and token output -vvv Print sniff processing information -i Show a list of installed coding standards -d Set the [key] php.ini value to [value] or [true] if value is omitted
前面筆者使用驗證的命令的路徑太長,後續若是要使用是極爲不方便的,因此筆者須要將這寫路徑加入到全局中,加入的命令以下
ln -s ~/.composer/vendor/bin/phpcs /usr/local/bin/phpcs ln -s ~/.composer/vendor/bin/phpcbf /usr/local/bin/phpcbf
當執行完成以後,可使用短命令來驗證是否加入全局成功,能夠用下方的命令
phpcs --help
執行成功以後,返回結果應該和上方完整路徑返回的一致。
phpcs默認的編碼格式並非php-cs,因此當不指定標準的時候,檢測的結果並不許確,但每次都手動指定也挺麻煩,因此筆者能夠設置一個默認標準,命令以下:
phpcs --config-set default_standard PSR2 phpcbf --config-set default_standard PSR2
如今筆者能夠用phpcs來真實的試驗了,筆者先準備一個PHP文件,文件裏面的內容以下代碼示例,能夠看出這份代碼並不符合PSR-2的風格規範
<?php function test_test(){ echo 'daxia'; } test();
phpcs /Users/tangqingsong/mycode/test.php
命令執行完成以後,能夠看到以下代碼提示,在提示中筆者能看到具體哪一行,提示級別,以及具體的提示緣由
FILE: /Users/song/mycode/test.php ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- FOUND 2 ERRORS AND 1 WARNING AFFECTING 3 LINES ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 | WARNING | [ ] A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is | | defined on line 3 and the first side effect is on line 8. 3 | ERROR | [x] Opening brace should be on a new line 8 | ERROR | [x] Expected 1 newline at end of file; 0 found ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Time: 79ms; Memory: 4Mb
phpcbf /Users/tangqingsong/mycode/test.php
命令執行完成以後,能夠看到以下返回提示,處理了哪一些文件,以及類型
PHPCBF RESULT SUMMARY ---------------------------------------------------------------------- FILE FIXED REMAINING ---------------------------------------------------------------------- /Users/song/mycode/test.php 2 1 ---------------------------------------------------------------------- A TOTAL OF 2 ERRORS WERE FIXED IN 1 FILE ---------------------------------------------------------------------- Time: 68ms; Memory: 4Mb
phpcs /Users/tangqingsong/mycode/test.php
執行完成以後,經過命令再次查看結果
FILE: /Users/song/mycode/test.php ---------------------------------------------------------------------------------------------------------------------------------------------- FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE ---------------------------------------------------------------------------------------------------------------------------------------------- 1 | WARNING | A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute | | logic with side effects, but should not do both. The first symbol is defined on line 3 and the first side effect is on line 9. ---------------------------------------------------------------------------------------------------------------------------------------------- Time: 71ms; Memory: 4Mb
能看到最開始檢測有三次不合格,但如今只剩下一處了;這裏說一下爲何phpcbf沒有幫徹底處理呢,由於phpcbf只能處理代碼風格等方式,而不能幫你處理裏面的命名與代碼實現規則,因此有少部分還須要人爲去更正,但並不會太多。
不多開發者只使用終端就開發代碼,一般都會用到編輯器,所以筆者也須要把phpcs和編輯器進行結合
1.設置->code style -> PHP 中選擇風格爲 psr1/2
2.設置->languages->php->code sniffer 中設置phpcs的路徑
3.設置->Editor->Inspections展開點擊右側的PHP,勾選下面的兩個PHP,選擇使用PSR2
下面還有一處,也要選中
如今筆者使用phpstorm的格式化,將會自動格式化成psr-2的風格。
通過上面的操做,phpstorm代碼格式化的規則基本與phpcs的規則基本一致了,但也有一小部分不一致,因此後面還要用到phpcs和phpcbf。
筆者若是每次都在終端去執行phpcs風格檢測花費時間可很多,爲了提升工做效率,能夠在phpstorm集成phpcs檢測規範的功能,設置路徑:Tools->External Tools->添加-> (/usr/local/bin/phpcs ) ($FileDir$/$FileName$)
若是每次都在終端去執行phpcbf格式化,仍是會有一些麻煩,因此筆者也能夠在phpstorm集成phpcbf自動格式化功能,設置路徑:Tools->External Tools->添加-> (/usr/local/bin/phpcbf ) ($FileDir$/$FileName$)
當前面一切準備就緒,筆者就能夠在git鉤子裏面增長強制的策略了,git鉤子腳本存放於項目下 .git/hooks/ 文件夾下,按照下面的步驟筆者來添加一個commit事件。
在你的項目根目錄下,使用vim命令或其餘方式,新增一個文件 ./.git/hooks/pre-commit,而後把下面的腳本放進去,以後再保存。
#!/bin/sh PHPCS_BIN=/usr/local/bin/phpcs PHPCS_CODING_STANDARD=PSR2 PHPCS_FILE_PATTERN="\.(php)$" FILES=$(git diff HEAD^..HEAD --stat) if [ "$FILES" == "" ]; then exit 0 fi for FILE in $FILES do echo "$FILE" | egrep -q "$PHPCS_FILE_PATTERN" RETVAL=$? if [ "$RETVAL" -eq "0" ] then PHPCS_OUTPUT=$($PHPCS_BIN --standard=$PHPCS_CODING_STANDARD $FILE) PHPCS_RETVAL=$? if [ $PHPCS_RETVAL -ne 0 ]; then echo $PHPCS_OUTPUT exit 1 fi fi done exit 0
須要注意的是讓這個文件有可執行權限,最直接的辦法就是設置爲777,參考命令以下:
chmod 777 .git/hooks/pre-commit
如今筆者故意讓php代碼風格不一致,而後使用git commit來提交,看看git是否會阻止提交,如下面這份代碼爲例
<?php function test_test(){ echo 'daxia'; } test();
能夠很明顯的看出來,這份代碼沒有按照駝峯命名法,大括號也沒用換行的兩處問題;把它保存在根目錄名爲test.php文件,而後執行git commit命令,以下
git add test.php && git commit . -m 'test'
命令執行後,git返回了以下信息,便終止了
FILE: /Users/song/mycode/work/xiaoyu/test.php ---------------------------------------------------------------------------------------------------------------------------------------------- FOUND 2 ERRORS AND 1 WARNING AFFECTING 3 LINES ---------------------------------------------------------------------------------------------------------------------------------------------- 1 | WARNING | [ ] A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should | | execute logic with side effects, but should not do both. The first symbol is defined on line 3 and the first side effect | | is on line 8. 3 | ERROR | [x] Opening brace should be on a new line 8 | ERROR | [x] Expected 1 newline at end of file; 0 found ---------------------------------------------------------------------------------------------------------------------------------------------- PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY ---------------------------------------------------------------------------------------------------------------------------------------------- Time: 63ms; Memory: 4Mb
驗證一下git是否commit成功,能夠執行下面的命令:
git status
返回結果以下
位於分支 develop 您的分支與上游分支 'origin/develop' 一致。 要提交的變動: (使用 "git reset HEAD <文件>..." 以取消暫存) 新文件: test.php
說明筆者前面的命令只成功執行了 git add . 然後面commit則成功阻擋了。
前面一個步驟筆者已經成功的在本地的commit鉤子中阻擋了觸發,可是任然有可能有夥伴會繞過,或者新項目沒有部署等,致使能夠最終提交上來的代碼仍是存在不符合psr-2風格,因此這個時候筆者就須要在服務端的push事件作一些處理。
這個時候筆者須要在服務器的鉤子事件中新增一個,pre-receive 文件。
在服務端去配置的時候遇到了幾個坑,後來筆者放棄了,有興趣的能夠留言或私信。
做者:湯青松
微信:songboy8888