推荐一款 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.git

来自 Laravel 的说明:laravel.com/github

几个代码规范的含义npm

  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 编码规范的说明了,推荐看下面这个:缓存

laravel-china.org/docs/psr/ps…安全

但我在实际使用时,除了可以按照上面说的规范来,还有一块重要的内容他们没提。bash

文件和类注释

主要包含以上内容块:文件说明、PHP 版本号、还有就是按顺序的这五要素:(category, package, author, license, link),并且这五要素排版要对齐哦,通常人我不告诉哦~~~

方法注释

主要包含:方法说明、空一行、参数块 (类型、参数名、含义 —— 这个须要对齐)、空一行、最后 return 类型。

安装 phpcs

使用 phpcs 以前,仍是须要先知道这个东西是什么吧?

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

摘自:github.com/squizlabs/P…

主要包含两个工具: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」系统下有效了!

固然根据官网的文档,还有其余方法,欢迎你们去尝试:

具体可参考:github.com/squizlabs/P… 中的「Installation」部分。

使用 phpcs

不管是本地仍是服务器,只要咱们安装好了,天然就能够开始使用了。最直观也是最简单的方法莫过于用命令行的方式了,如:

phpcs php_path

// or

phpcs php_dir
复制代码

但想到咱们是用 IDE 写代码的,并且是但愿实时看到效果的,因此下面尝试在几个 IDE 下看看如何使用。

安装 VSCode 插件

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

参考:marketplace.visualstudio.com/items?itemN…

配置插件

因为项目使用的是系统的 phpcs,因此须要在 user setting 中配置可执行路径和本身自定义的编写风格

这时候咱们去看看咱们的代码界面,是否是有了 phpcs 的提示了:

![2018-05-10 09.29.08](http://ow20g4tgj.bkt.clouddn.com/2018-05-10-2018-05-10 09.29.08.gif)

安装 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 github.com/WickedRepor… 的写法:

#!/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,怎么作这一流程式检测?

相关文章
相关标签/搜索