GitHub上没有这样的linter,所以你必须自己写一个。
PHP_CodeSniffer 是 PHP 世界中最著名和最强大的 linter,所以这里是基于 PHP_CodeSniffer 3.5.2 的快速而肮脏的实现,它使用 similar_text 函数来比较函数名和注释字符串,如果百分比超过 60%,它会将此功能标记为错误,并显示消息“包含异常评论”。
文件src/Standards/StackOverflow/Sniffs/Commenting/UnusualCommentSniff.php
<?php
namespace PHP_CodeSniffer\Standards\StackOverflow\Sniffs\Commenting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
class UnusualCommentSniff implements Sniff
{
public function register()
{
return [T_FUNCTION];
}
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$find = Tokens::$methodPrefixes;
$find[] = T_WHITESPACE;
$commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true);
if ($tokens[$commentEnd]['code'] != T_DOC_COMMENT_CLOSE_TAG) {
return;
}
$commentStart = $tokens[$commentEnd]['comment_opener'];
$shortDesc = $this->findShortDescriptionInComment($phpcsFile, $commentStart, $commentEnd);
$funcName = $phpcsFile->getDeclarationName($stackPtr);
similar_text($funcName, $shortDesc, $percent);
if ($percent > 60) {
$error = 'Contains unusual comment';
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'code');
if ($fix) {
$fixer = $phpcsFile->fixer;
for ($i = $commentStart; $i < $commentEnd + 1; $i++) {
$fixer->replaceToken($i, '');
}
}
}
}
protected function findShortDescriptionInComment($phpcsFile, $commentStart, $commentEnd)
{
$tokens = $phpcsFile->getTokens();
$empty = [
T_DOC_COMMENT_WHITESPACE,
T_DOC_COMMENT_STAR,
];
$short = $phpcsFile->findNext($empty, $commentStart + 1, $commentEnd, true);
if ($short === false) {
return;
}
$shortContent = null;
if ($tokens[$short]['code'] === T_DOC_COMMENT_STRING) {
$shortContent = $tokens[$short]['content'];
$shortEnd = $short;
for ($i = ($short + 1); $i < $commentEnd; $i++) {
if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) {
if ($tokens[$i]['line'] === ($tokens[$shortEnd]['line'] + 1)) {
$shortContent .= $tokens[$i]['content'];
$shortEnd = $i;
} else {
break;
}
}
}
}
return $shortContent;
}
}
POC
像这样构造文件和目录
$ pwd
/home/gasolwu/Code/PHP_CodeSniffer/src/Standards
$ git describe
3.5.2-89-g80ebd4a1a
$ tree -C StackOverflow/
StackOverflow/
├── ruleset.xml
└── Sniffs
└── Commenting
└── UnusualCommentSniff.php
2 directories, 2 files
$ cat StackOverflow/ruleset.xml
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Zend" xsi:noNamespaceSchemaLocation="../../../phpcs.xsd">
</ruleset>
为测试准备输入文件
$ cat input.php
<?php
class Foo
{
/**
* Get warning file info
*/
private function getWarningFileInfos() {
}
/**
* Compute the speed
*/
public function computeSpeed() {
}
/**
* This comment contains some useful information
* So that should not be deleted
*/
public function shoot() {
}
}
使用命令phpcs运行
$ bin/phpcs --standard=Stackoverflow ./input.php
FILE: /data1/home/admin/gasolwu/Code/PHP_CodeSniffer/input.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
----------------------------------------------------------------------
9 | ERROR | [x] Contains unusual comment
15 | ERROR | [x] Contains unusual comment
----------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
Time: 44ms; Memory: 3.75MB
通过命令phpcbf自动修复此类错误
$ bin/phpcbf --standard=Stackoverflow ./input.php
PHPCBF RESULT SUMMARY
-----------------------------------------------------------------------------
FILE FIXED REMAINING
-----------------------------------------------------------------------------
/data1/home/admin/gasolwu/Code/PHP_CodeSniffer/input.php 2 0
-----------------------------------------------------------------------------
A TOTAL OF 2 ERRORS WERE FIXED IN 1 FILE
-----------------------------------------------------------------------------
Time: 52ms; Memory: 3.75MB
$ cat input.php
<?php
class Foo
{
private function getWarningFileInfos() {
}
public function computeSpeed() {
}
/**
* This comment contains some useful information
* So that should not be deleted
*/
public function shoot() {
}
}