您现在的位置是:首页 >技术交流 >11. Laravel基于php_codesniffer代码风格检测网站首页技术交流
11. Laravel基于php_codesniffer代码风格检测
简介11. Laravel基于php_codesniffer代码风格检测
-
安装插件
composer require squizlabs/php_codesniffer --dev composer require brainmaestro/composer-git-hooks:* --dev
-
运行测试
root@d92a8d4c6792:/var/www/ogenes/Genes-Admin# ./vendor/bin/phpcs --standard=PSR1,PSR2 app/ routes/ config/
-
自定义校验规则
#vim _php_codesniffer.xml <?xml version="1.0"?> <ruleset name="custom"> <description>The custom coding standard.</description> <!-- See the [documented coding standard](http://symfony.com/doc/current/contributing/code/standards.html) This CodeSniffer standard does not yet enforce the following: # Structure * Declare class properties before methods; * Declare public methods first, then protected ones and finally private ones. * Use namespaces for all classes; * Add PHPDoc blocks for all classes, methods, and functions; * The @package and @subpackage annotations are not used. * Use uppercase strings for constants with words separated with underscores # Naming Conventions * Use underscores for option, argument, parameter names; --> <!-- 文件 --> <!-- 所有 PHP 文件都必须使用 UTF-8 编码,文件头不允许出现 BOM 标记。 --> <rule ref="Generic.Files.ByteOrderMark"/> <!-- 所有 PHP 文件都必须使用 Unix LF 格式作为行的结尾。 --> <rule ref="Generic.Files.LineEndings"> <properties> <property name="eolChar" value=" "/> </properties> </rule> <!-- 在只包含有 PHP 代码的文件中不允许使用 ?> 作为结束标签。 --> <rule ref="Zend.Files.ClosingTag"/> <!-- 不允许使用short tag"<?"开头,必须使用"<?php"开头. --> <rule ref="Generic.PHP.DisallowShortOpenTag"/> <!-- 缩进 --> <!-- 代码缩进统一为 4 个空格,不允许使用 tab。 --> <rule ref="Generic.WhiteSpace.ScopeIndent"> <exclude name="Generic.WhiteSpace.ScopeIndent.Incorrect" /> <exclude name="Generic.WhiteSpace.ScopeIndent.IncorrectExact" /> </rule> <rule ref="Generic.WhiteSpace.DisallowTabIndent"/> <!-- 行 --> <!-- 在非空行的结尾不允许出现尾随空白 --> <rule ref="Squiz.WhiteSpace.SemicolonSpacing"/> <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"> <properties> <property name="ignoreBlankLines" value="true"/> </properties> <exclude-pattern>*/app/Facades/*</exclude-pattern> <exclude-pattern>*/app/Exceptions/*</exclude-pattern> <exclude-pattern>*/app/Console/Kernel.php</exclude-pattern> <exclude-pattern>*/bootstrap/*</exclude-pattern> </rule> <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile"> <severity>0</severity> </rule> <!-- 每一行代码只允许一条语句。 --> <rule ref="Generic.Formatting.DisallowMultipleStatements"/> <!-- 方法与方法之间,都至少有一个空行。 --> <rule ref="Squiz.WhiteSpace.FunctionSpacing"> <properties> <property name="spacing" value="1"/> </properties> <exclude name="Squiz.WhiteSpace.FunctionSpacing.AfterLast" /> <exclude name="Squiz.WhiteSpace.FunctionSpacing.BeforeFirst" /> </rule> <!-- PHP 关键字 和 true/false/null --> <!-- PHP关键字必须使用小写。 --> <rule ref="Generic.PHP.LowerCaseKeyword" /> <!-- 关键字 true, false 和 null 必须使用小写。 --> <rule ref="Generic.PHP.LowerCaseConstant"/> <!-- =、=> 等操作符的前后都必须有一个空格 --> <rule ref="Squiz.WhiteSpace.OperatorSpacing"> <exclude name="Squiz.WhiteSpace.OperatorSpacing.SpacingAfter" /> </rule> <!-- 字符串 --> <!-- 不允许对两个不带变量的字符串使用连接符,应该用一个字符串表示. --> <rule ref="Generic.Strings.UnnecessaryStringConcat"/> <!-- 注释 --> <!-- 每个函数/方法必须有文字描述 --> <rule ref="PEAR.Commenting.FunctionComment"> <exclude-pattern>*/app/Console/Kernel.php</exclude-pattern> <exclude-pattern>*/app/Exceptions/*</exclude-pattern> <exclude-pattern>*/app/Facades/*</exclude-pattern> <exclude name="PEAR.Commenting.FunctionComment.MissingReturn" /> <exclude name="PEAR.Commenting.FunctionComment.MissingParamComment" /> <exclude name="PEAR.Commenting.FunctionComment.SpacingAfterParamType" /> <exclude name="PEAR.Commenting.FunctionComment.SpacingAfterParamName" /> <exclude name="PEAR.Commenting.FunctionComment.ExtraParamComment" /> </rule> <!-- 命名空间(namespace)和 use 关键字的使用 --> <!-- 在 use 定义块之后必须有一个空行 --> <rule ref="PSR2.Namespaces.UseDeclaration"> <exclude-pattern>*/app/Models/*</exclude-pattern> </rule> <!-- 类、类属性和类方法 --> <!-- 类、接口和特征的名称必须以大写开头,如:PartnerInfo、Partner_Info --> <rule ref="Squiz.Classes.ValidClassName"/> <rule ref="Squiz.Functions.LowercaseFunctionKeywords"/> <!-- 一个文件中只能包含类、接口和特征中的一个,不允许出现多个. --> <rule ref="Generic.Files.OneClassPerFile"/> <!-- 一个文件中只能包含类、接口和特征中的一个,不允许出现多个. --> <rule ref="Generic.Files.OneInterfacePerFile"/> <!-- 类常量 --> <!-- 类的常量定义必须全部为大写,并用下划线分割每个单词,如:BRAND_DRAFT、BRAND_DELETED --> <rule ref="Generic.NamingConventions.UpperCaseConstantName"/> <!-- 函数定义 --> <rule ref="Squiz.Functions.FunctionDeclaration"/> <rule ref="Squiz.NamingConventions.ValidFunctionName"> <exclude name="Squiz.NamingConventions.ValidFunctionName.PrivateNoUnderscore" /> </rule> <!-- 函数参数 --> <!-- 在参数队列中,逗号之前不允许出现空格,逗号之后必须有一个空格。 在方法的参数队列中定义带默认值的参数时,必须放到队列的末尾。 参数队列可以被写到多行,每一行都需要用一个同样的缩进, 第一个参数必须被写到新的一行,并且每一行只能有一个参数。 当参数队列被写到多行时,结束括号和开始大括号必须被写到一行,两者之间必须有一个空格。 --> <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing"> <properties> <property name="equalsSpacing" value="1"/> </properties> </rule> <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint"> <severity>0</severity> </rule> <!-- 类方法和一般函数(function)的调用 --> <!-- 当调用一个类方法或者一般函数时,方法或函数名称和开始括号之间不允许出现空格, 在开始括号之后和结束括号之前都不允许出现空格。 在参数队列里,逗号之前不允许出现空格,逗号之后必须有一个空格。 参数队列可以被写到多行,每一行都需要用一个同样的缩进, 第一个参数必须被写到新的一行,并且每一行只能有一个参数。 --> <rule ref="PEAR.WhiteSpace.ObjectOperatorIndent"/> <rule ref="PEAR.Functions.FunctionCallSignature"> <exclude name="PEAR.Functions.FunctionCallSignature.Indent"/> <exclude name="PEAR.Functions.FunctionCallSignature.CloseBracketLine"/> <exclude name="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket"/> </rule> <!-- 控制结构 --> <!-- 控制结构的一般样式规则如下: 在控制结构的关键字后面必须有一个空格 开始括号之后不能出现空格 结束括号之前不能出现空格 在结束括号和开始大括号之间必须有一个空格 代码块(结构体)必须有一个缩进 结束大括号必须在代码块结束后的下一行 每个代码块必须被封装到一个大括号内,以标准化代码结构,同时减少在添加代码时间引入错误的可能性。 --> <rule ref="Squiz.ControlStructures.ControlSignature"/> <!-- 必须用 elseif 代替 else if,让控制关键字看上去是一个单词,同时避免出现代码块逻辑错误。 --> <rule ref="PSR2.ControlStructures.ElseIfDeclaration"/> </ruleset>
# -s 参数会显示生效的规则,便于调试。 root@d92a8d4c6792:/var/www/ogenes/Genes-Admin# ./vendor/bin/phpcs --standard=./_php_codesniffer.xml -s app/ FILE: /var/www/ogenes/Genes-Admin/app/Providers/MD5HashServiceProvider.php ---------------------------------------------------------------------------------------------------- FOUND 1 ERROR AFFECTING 1 LINE ---------------------------------------------------------------------------------------------------- 32 | ERROR | Missing doc comment for function provides() | | (PEAR.Commenting.FunctionComment.Missing) ---------------------------------------------------------------------------------------------------- Time: 207ms; Memory: 10MB
-
基于git修改的文件检测,同时支持docker
#vim php_codesniffer #!/usr/bin/env bash appPath=ogenes/Genes-Admin phpversion=php81 hasError=false [ -z ${DOCKER_LNMP+x} ]&&DOCKER_LNMP=N CHANGE_FILES=$(git diff --name-only --diff-filter=ACM | grep -E '.(php|phtml)$') for cf in ${CHANGE_FILES[@]} do if [ $DOCKER_LNMP = "Y" ]; then ret=`docker exec $phpversion bash -c "cd $appPath; ./vendor/bin/$1 --standard=./_php_codesniffer.xml $cf"` else ret=`$phpversion ./vendor/bin/$1 --standard=./_php_codesniffer.xml $cf` fi if [ -n "$ret" ];then echo "${ret}" fi tmpError=`echo $ret| grep -E 'FOUND [1-9]+ ERROR'` if [ -n "$tmpError" ]; then hasError=true fi done if $hasError then exit 1 else echo 'Success!' exit 0 fi
-
加入composer 命令
修改 composer.json "scripts": { "post-autoload-dump": [ "Illuminate\Foundation\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi", "php81 ./vendor/bin/cghooks update", "php81 ./vendor/bin/phpcs --config-set php_version 80108", "php81 ./vendor/bin/phpcs --config-set colors 1", "php81 ./vendor/bin/phpcs --config-set encoding utf-8" ], ……………… ……………… "lint": "./php_codesniffer phpcs", "lint-fix": "./php_codesniffer phpcbf" }, composer update
-
测试
#随便修改 AuthController.php 一行代码 root@d92a8d4c6792:/var/www/ogenes/Genes-Admin# composer run lint > ./php_codesniffer phpcs FILE: /var/www/ogenes/Genes-Admin/app/Http/Controllers/User/AuthController.php ------------------------------------------------------------------------------ FOUND 4 ERRORS AFFECTING 4 LINES ------------------------------------------------------------------------------ 12 | ERROR | [ ] Missing doc comment for function login() 34 | ERROR | [x] Expected 1 blank line after function; 0 found 35 | ERROR | [ ] Missing doc comment for function logout() 44 | ERROR | [ ] Missing doc comment for function userinfo() ------------------------------------------------------------------------------ PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY ------------------------------------------------------------------------------ Time: 122ms; Memory: 10MB Script ./php_codesniffer phpcs handling the lint event returned with error code 1 root@d92a8d4c6792:/var/www/ogenes/Genes-Admin#
-
加上钩子,pre-commit强制检测
"extra": { "laravel": { "dont-discover": [] }, "hooks": { "pre-commit": [ "echo committing as $(git config user.name).", "composer run lint" ] } }, composer update
-
提交测试
#docker环境中,在宿主机 ➜ Genes-Admin git:(ogenes) ✗ export DOCKER_LNMP=Y ➜ Genes-Admin git:(ogenes) ✗ git add . ➜ Genes-Admin git:(ogenes) ✗ git commit -m '代码风格检测' committing as 易怀源. > ./php_codesniffer phpcs FILE: .../ogenes/Genes-Admin/app/Http/Controllers/User/AuthController.php ---------------------------------------------------------------------- FOUND 4 ERRORS AFFECTING 4 LINES ---------------------------------------------------------------------- 12 | ERROR | [ ] Missing doc comment for function login() 34 | ERROR | [x] Expected 1 blank line after function; 0 found 35 | ERROR | [ ] Missing doc comment for function logout() 44 | ERROR | [ ] Missing doc comment for function userinfo() ---------------------------------------------------------------------- PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY ---------------------------------------------------------------------- Time: 133ms; Memory: 10MB Script ./php_codesniffer phpcs handling the lint event returned with error code 1 #自动修正 ➜ Genes-Admin git:(ogenes) ✗ composer run lint-fix > ./php_codesniffer phpcbf PHPCBF RESULT SUMMARY ---------------------------------------------------------------------- FILE FIXED REMAINING ---------------------------------------------------------------------- ...dmin/app/Http/Controllers/User/AuthController.php 1 3 ---------------------------------------------------------------------- A TOTAL OF 1 ERROR WERE FIXED IN 1 FILE ---------------------------------------------------------------------- Time: 192ms; Memory: 10MB Success! #无法自动修正的手动修正 #然后测试 ➜ Genes-Admin git:(ogenes) ✗ git add . ➜ Genes-Admin git:(ogenes) ✗ git commit -m '代码风格检测' committing as 易怀源. > ./php_codesniffer phpcs Success! [ogenes 1941357] 代码风格检测 5 files changed, 458 insertions(+), 74 deletions(-) create mode 100644 _php_codesniffer.xml create mode 100755 php_codesniffer
-
修正历史提交的文件
#自动修正 root@d92a8d4c6792:/var/www/ogenes/Genes-Admin# ./vendor/bin/phpcbf --standard=./_php_codesniffer.xml app config routes #手动修正 root@d92a8d4c6792:/var/www/ogenes/Genes-Admin# ./vendor/bin/phpcs --standard=./_php_codesniffer.xml -s app config routes
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。