推薦一款 phpcs 插件規範 Laravel 代碼 (規範從本地寫代碼到版本控制)

我相信每一個公司都有一套完備的代碼規範標準,但標準是標準,如何能有效的讓全部人遵照,那就要工具的輔助和實時提醒了。php

如前端 vue 的你們基本都會使用 eslint 來約束咱們的代碼,一旦多一個空格都會提示你有問題,當 npm run dev 或者 npm run watch 就會提示你哪哪哪不符合規範。前端

在 Laravel 開發中,照樣也有相似的工具,這也是本文的所要推薦的:phpcsvue

在開始使用 phpcs 以前,咱們簡單來講說 Laravel 的代碼規範標準laravel

Laravel 代碼規範

Laravel follows the PSR-2 coding standard and the PSR-4 autoloading standard.

來自 Laravel 的說明:https://laravel.com/git

幾個代碼規範的含義github

  1. PSR-0 自動加載規範 (已棄用)
  2. PSR-1 基礎編碼規範
  3. PSR-2 編碼風格規範
  4. PSR-3 日誌接口規範
  5. PSR-4 自動加載規範
  6. PSR-5 PHPDoc 標準 (未經過)
  7. PSR-6 緩存接口規範
  8. PSR-7 HTTP 消息接口規範
  9. PSR-8 Huggable 接口 (未經過)
  10. PSR-9 項目安全問題公示 (未經過)
  11. PSR-10 項目安全上報方法 (未經過)
  12. PSR-11 容器接口
  13. PSR-12 編碼規範擴充
  14. PSR-13 超媒體連接
  15. PSR-14 事件分發器 (未經過)
  16. PSR-15 HTTP 請求處理器
  17. PSR-16 緩存接口

其實如今不少網站已經掛出 PSR-2 編碼規範的說明了,推薦看下面這個:npm

https://laravel-china.org/docs/psr/psr-2-coding-style-guide/1606緩存

但我在實際使用時,除了可以按照上面說的規範來,還有一塊重要的內容他們沒提。安全

文件和類註釋

主要包含以上內容塊:文件說明、PHP 版本號、還有就是按順序的這五要素:(category, package, author, license, link),並且這五要素排版要對齊哦,通常人我不告訴哦~~~bash

方法註釋

主要包含:方法說明、空一行、參數塊 (類型、參數名、含義 —— 這個須要對齊)、空一行、最後 return 類型。

安裝 phpcs

使用 phpcs 以前,仍是須要先知道這個東西是什麼吧?

PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.

摘自:https://github.com/squizlabs/PHP_CodeSniffer

主要包含兩個工具:phpcs 和 phpcbf (這個以後再說)。phpcs 主要對 PHPJavaScriptCSS 文件定義了一系列代碼規範標準,如咱們會使用的,也是 Laravel 使用的 PHP PSR-2標準,可以檢測出不符合咱們定義的代碼規範的代碼,併發出警告和錯誤,固然咱們也能夠設置報錯的級別。

對於 phpcs 的使用,主要有兩個途徑:

  1. 在本地開發過程當中,實時對咱們的代碼進行檢測,讓代碼提交版本庫時,就已經符合規範標準了;
  2. 在服務器對提交的代碼進行檢測,若是不符合標準的,則不入代碼庫,打回要求修改。

下面咱們開始說說根據不一樣方法,如何安裝 phpcs 工具的。

composer

composer global require "squizlabs/php_codesniffer"

寫 Laravel 代碼的同窗,對使用 composer 應該很熟悉了,這種方法比較推崇。但主要區分爲是「全局安裝」仍是按「項目安裝」。

這裏我本人推薦採用「全局安裝」,能夠在各個 IDE 上直接填入全局安裝的 phpcs 可執行路徑。但若是你的版本庫是使用「git」的話,那我推薦使用「項目安裝」,下文就知道緣由了。

注: 我使用這種方式「全局安裝」後,發現每回都關聯不了「VSCode」,這個緣由待查。

pear

安裝 pear

curl -O https://pear.php.net/go-pear.phar
php -d detect_unicode=0 go-pear.phar
開始安裝配置,

先選擇 1 (change the Installation Base);

輸入:/usr/local/pear

再選擇 4 (change the Binaries directory),

輸入:/usr/local/bin

開始安裝 PHP_CodeSniffer

pear install PHP_CodeSniffer

在 MacOS 系統下:

在 Centos Linux 系統下安裝效果:

此方法比較有效果,並且也符合在多系統上嘗試,好比本人同時在「Mac」和 「Linux」下均可以正常安裝和使用。

注:我沒在「Windows」環境下嘗試,還沒有知道效果。

brew

brew install php-code-sniffer

這種方法顯然在「Mac」系統下有效了!

固然根據官網的文檔,還有其餘方法,歡迎你們去嘗試:

具體可參考: https://github.com/squizlabs/PHP_CodeSniffer 中的「Installation」部分。

使用 phpcs

不管是本地仍是服務器,只要咱們安裝好了,天然就能夠開始使用了。最直觀也是最簡單的方法莫過於用命令行的方式了,如:

phpcs php_path

// or

phpcs php_dir

但想到咱們是用 IDE 寫代碼的,並且是但願實時看到效果的,因此下面嘗試在幾個 IDE 下看看如何使用。

安裝 VSCode 插件

在插件界面,搜索:phpcs,安裝便可。

參考: https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs

配置插件

因爲項目使用的是系統的 phpcs,因此須要在 user setting 中配置可執行路徑和本身自定義的編寫風格

這時候咱們去看看咱們的代碼界面,是否是有了 phpcs 的提示了:

2018-05-10 09.29.08

安裝 PhpStorm 插件

直接看圖,不須要作過多的說明了。

基本到此,phpcs 的插件就可使用了。

版本檢測規範

咱們但願在團隊項目代碼提交版本庫以前「pre-commit」就能檢測
出不符合「PSR-2」 標準的代碼文件。不管是 svn 或者 git,都能在「pre-commit」獲取提交版本庫的代碼文件,而後再利用「phpcs」去檢測每一個文件是否符合規範。

svn

因爲每一個 svn 在服務端都有對應 hooks 文件夾,能夠在「pre-commit」時,驗證代碼的規範,直接上文件,比較好理解:

#!/bin/bash

LOG="/tmp/svn.log"
touch ${LOG}

REPOS="$1"
TXN="$2"
echo "REPOS: $REPOS" > ${LOG}
echo "TXN: $TXN" >> ${LOG}

SVNLOOK="/usr/bin/svnlook"
PHPCS="/usr/bin/phpcs"

# php file extension
PHP_EXT="php"

MSG_MIN_CHAR_NUM=3

MAX_PNG_SIZE=2048

PROHIBITED_FILES=(
)

TMP_DIR="/tmp/svn"
if [[ -d ${TMP_DIR} ]]; then
    rm -r ${TMP_DIR}
fi
mkdir -p ${TMP_DIR}

function check_php_syntax {
local php_file=$1
echo `${PHPCS} ${php_file} 2>&1`
}

function create_file {
local file_name=$1
# Create tmp file and copy content
tmp_file="${TMP_DIR}/${file_name}"
mkdir -p "$(dirname "${tmp_file}")" && touch "${tmp_file}"
${SVNLOOK} cat -t "${TXN}" "${REPOS}" "${file_name}" > ${tmp_file}
}

changed_info_str=`${SVNLOOK} changed -t "${TXN}" "${REPOS}"`
IFS=$'\n' read -rd '' -a changed_infos <<<"${changed_info_str}"

php_error_msg=""
for changed_info in "${changed_infos[@]}"; do
    # Prevent commiting file that contains space in its filename
    echo ${changed_info} >> ${LOG}
    operation=`echo ${changed_info} | awk '{print $1}'`
    if [[ ${operation} = "A" ]] && [[ `echo ${changed_info} | awk '{print NF}'` -gt 2 ]]; then
        echo "Please do not commit file that contains space in its filename!" 1>&2
        exit 1
    fi
    file_name=`echo ${changed_info} | awk '{print $2}'`
    echo "operation: ${operation}, file: ${file_name}, ext: ${ext}" >> ${LOG}

    # Check prohibit-commit files
    for prohibited_file in ${PROHIBITED_FILES[@]}; do
        if [[ ${file_name} = ${prohibited_file} ]]; then
            echo "${file_name} is not allowed to be changed!" 1>&2
            exit 1
        fi
    done

    ext=`echo ${file_name} | awk -F"." '{print $NF}'`

    if [[ ${operation} = "U" ]] || [[ ${operation} = "A" ]]; then
        tmp_file="${TMP_DIR}/${file_name}"

        # Check lua syntax
        if [[ ${ext} = ${PHP_EXT} ]]; then
            echo "Check syntax of ${tmp_file}" >> ${LOG}
            create_file ${file_name}
            error_msg=`check_php_syntax ${tmp_file}`
            if [[ `echo ${error_msg} | sed 's/\n//g'` != "" ]]; then
                php_error_msg="${php_error_msg}\n${error_msg}"
            fi
        fi
    fi
done

rm -r ${TMP_DIR}

if [[ ${php_error_msg} != "" ]]; then
    echo "php error: ${php_error_msg}" >> ${LOG}
        echo "Please fix the error in your php program:${php_error_msg}" 1>&2

    exit 1
fi

exit 0

這就是咱們想要看到的效果了,不管 IDE 的實時提示,仍是提交代碼時的檢測反饋,都會告訴咱們哪裏格式不符合規範了。

git

這裏主要參考 WickedReports/phpcs-pre-commit-hook https://github.com/WickedReports/phpcs-pre-commit-hook 的寫法:

#!/bin/sh

PROJECT=`php -r "echo dirname(dirname(dirname(realpath('$0'))));"`
STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`

# Determine if a file list is passed
if [ "$#" -eq 1 ]
then
    oIFS=$IFS
    IFS='
    '
    SFILES="$1"
    IFS=$oIFS
fi
SFILES=${SFILES:-$STAGED_FILES_CMD}

echo "Checking PHP Lint..."
for FILE in $SFILES
do
    php -l -d display_errors=0 $PROJECT/$FILE
    if [ $? != 0 ]
    then
        echo "Fix the error before commit."
        exit 1
    fi
    FILES="$FILES $PROJECT/$FILE"
done

if [ "$FILES" != "" ]
then
    echo "Running Code Sniffer. Code standard PSR2."
    /usr/local/bin/phpcs --standard=PSR2 --colors --encoding=utf-8 -n -p $FILES
    if [ $? != 0 ]
    then
        echo "Fix the error before commit!"
        echo "Run"
        echo "  ./vendor/bin/phpcbf --standard=PSR2 $FILES"
        echo "for automatic fix or fix it manually."
        exit 1
    fi
fi

exit $?

咱們把該文件內容寫入「.git/hooks/pre-commit」中,而後再提交一個文件,看看運行效果。

在實驗以前,咱們先調用本地的 phpcs 插件,看看咱們的一個文件代碼的規範狀況:

phpcs --standard=PSR2 --encoding=utf-8 -n -p app/Http/Controllers/ApplyController.php

運行結果提示:

E 1 / 1 (100%)



FILE: /Users/app/Http/Controllers/ApplyController.php
------------------------------------------------------------------------------------------------------
FOUND 4 ERRORS AFFECTING 3 LINES
------------------------------------------------------------------------------------------------------
 17 | ERROR | [x] Opening brace should be on a new line
 60 | ERROR | [x] Opening parenthesis of a multi-line function call must be the last content on the
    |       |     line
 62 | ERROR | [x] Multi-line function call not indented correctly; expected 12 spaces but found 16
 62 | ERROR | [x] Closing parenthesis of a multi-line function call must be on a line by itself
------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 4 MARKED SNIFF VIOLATIONS AUTOMATICALLY
------------------------------------------------------------------------------------------------------

Time: 87ms; Memory: 6Mb

主要報錯在於:

60 行: output函數

17 行:

好了,咱們執行 git commit 試試:

接着咱們把這幾個不規範的地方改了以後,一樣運行本地方法,返回結果:

phpcs --standard=PSR2 --encoding=utf-8 -n -p app/Http/Controllers/ApplyController.php
. 1 / 1 (100%)


Time: 44ms; Memory: 6Mb

咱們再執行 git commit 試試:

完美了!

注:「svn」和「git」的區別在於,svn 是放在服務器上作「pre-commit」檢測的,而「git」是在本地本項目中的,這也是上文說的,若是你用 git 作版本庫,推薦你用「composer」項目安裝的方式安裝工具。

總結

本文以本地 Mac 系統和服務器 Linux 系統爲安裝端,以 VSCode 和 PHPStorm 兩大主流 IDE 做爲使用端,以 svn 和 git 爲版本庫爲例,較爲完整而又系統流程的說一說「phpcs」的使用,但願對你們有所幫助!

最後留個小問題:若是你使用 Docker 和 git,怎麼作這一流程式檢測?

相關文章
相關標籤/搜索