bmitch/codor

自定义PHPCS sniffs以查找代码异味。

1.2.3 2022-06-17 20:31 UTC

README

👃 💩 自定义PHP代码嗅探器sniffs,帮助查找代码异味(臭味)。

Build Status codecov Scrutinizer Code Quality Code Climate Packagist Packagist License

灵感来源: https://github.com/object-calisthenics/phpcs-calisthenics-rules

这是什么?

本包是一组自定义的Sniffs,用于PHP Code Sniffer,您可以在CI构建中使用它以确保代码库的完整性。

兼容性

  • PHP 7.1+ 请使用v1.0.0及以上版本。
  • PHP 5.6及以下请使用v1.0.0以下任何版本。

如何安装?

通过Composer安装

composer require bmitch/codor --dev

如何使用?

在项目的根目录下创建一个PHPCS规则集XML(codor.xml或您想要的任何文件名)文件。

<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="Project">
    <description>Project Coding Standard</description>

    <rule ref="vendor/bmitch/codor/src/Codor/ruleset.xml"/>
</ruleset>

然后使用以下命令运行它:

vendor/bin/phpcs --standard=codor.xml src 

其中src是您要检查的源代码位置。

省略sniffs

您可能不想运行提供的所有sniffs,因此可以使用--exclude标志指定要排除的sniffs,例如:

vendor/bin/phpcs --standard=codor.xml --exclude=Codor.ControlStructures.NoElse src

(如果要排除多个,只需用逗号分隔即可)

运行特定sniffs

或者,您也可以指定要运行的特定sniffs

vendor/bin/phpcs --standard=codor.xml --sniffs=Codor.ControlStructures.NoElse src

在特定代码片段上抑制sniffs

请参阅PHPCS文档
https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#ignoring-files-and-folders

包含的sniffs

Codor.ControlStructures.NoElse

不允许任何elseelseif语句。

if ($foo) {
    return 'bar';
} else {
    return 'baz';
}

if ($foo) {
    return 'bar';
}
return 'baz';

Codor.Files.FunctionLength

函数/方法不得超过20行。

public function foo()
{
    // more than 20 lines
}

public function foo()
{
    // no more than 20 lines
}

Codor.Files.FunctionParameter

函数/方法不得超过3个参数。

public function foo($bar, $baz, $bop, $portugal)
{
    // 
}

public function foo($bar, $baz, $bop)
{
    // 
}

Codor.Files.ReturnNull

函数/方法不得返回null

public function getAdapter($bar)
{
    if ($bar === 'baz') {
        return new BazAdapter;
    }
    return null;
}

public function getAdapter($bar)
{
    if ($bar === 'baz') {
        return new BazAdapter;
    }
    return NullAdapter;
}

Codor.Files.MethodFlagParameter

函数/方法不能有默认为布尔值的参数。

public function getCustomers($active = true)
{
    if ($active) {
        // Code to get customers from who are active
    }
    
    // Code to get all customers
}

public function getAllCustomers()
{    
    // Code to get all customers
}

public function getAllActiveCustomers()
{    
    // Code to get customers from who are active
}

Codor.Classes.ClassLength

类不得超过200行。

class ClassTooLong
{
    // More than 200 lines
}

class ClassNotTooLong
{
    // No more than 200 lines
}

Codor.Classes.ConstructorLoop

类构造函数不能包含任何循环。

public function __construct()
{
    for($index = 1; $index < 100; $index++) {
        // foo
    }
}

public function __construct()
{
    $this->someMethod();
}

private function someMethod()
{
    for($index = 1; $index < 100; $index++) {
        // foo
    }
}

Codor.Classes.Extends

如果类继承另一个类,则发出警告。目标是促进组合而非继承(https://en.wikipedia.org/wiki/Composition_over_inheritance)。

class GasolineCar extends Vehicle
{
    //
}

class GasolineVehicle extends Vehicle
{
    //
}

class Vehicle
{
    private $fuel;
    
    public function __construct(FuelInterface $fuel)
    {
        $this->fuel;    
    }
}

class Gasoline implements FuelInterface
{

}

$gasolineCar = new Vehicle($gasoline);

Codor.Classes.FinalPrivate

最终类不应包含受保护的函数或变量。应使用private。

final class Foo 
{
    protected $baz;

    protected function bar()
    {
        //
    }
}

final class Foo 
{
    private $baz;

    private function bar()
    {
        //
    }
}

Codor.Classes.NewInstance

类不应实例化对象。应使用依赖注入。

class NewInConstructor
{
    private MyClass $myClass;

    public function __construct()
    {
        $this->myClass = new MyClass();
    }
}

class NewInConstructor
{
    private MyClass $myClass;

    public function __construct(MyClass $myClass)
    {
        $this->myClass = $myClass;
    }
}

Codor.Classes.PropertyDeclaration

如果您的类使用未声明的成员变量,则产生错误。如果类继承自另一个类,则只发出警告。

class Foo 
{
    private function bar()
    {
        $this->baz = 13;
    }
}

class Foo 
{
    private $baz;
    
    private function bar()
    {
        $this->baz = 13;
    }
}

Codor.Files.FunctionNameContainsAndOr

函数/方法不能包含"And"或"Or"。这可能是函数执行多项任务的迹象。

public function validateStringAndUpdateDatabase()
{
    // code to validate string
    // code to update database
}

public function validateString()
{
    // code to validate string
}

public function updateDatabase()
{
    // code to update database
}

Codor.Files.IndentationLevel

函数/方法不能有超过2层的缩进。

public function foo($collection)
{
    foreach ($collection as $bar) {
        foreach ($bar as $baz) {
            //
        }
    }
}

public function foo($collection)
{
    foreach ($collection as $bar) {
        $this->process($bar);
    }
}

private function process($bar)
{
    foreach ($bar as $baz) {
        //
    }
}

Codor.ControlStructures.NestedIf

不允许嵌套的if语句。

public function allowedToDrink($person)
{
    if ($person->age === 19) {
        if ($person->hasValidId()) {
            return true;
        }
    }
    
    return false;
}

public function allowedToDrink($person)
{
    if ($person->age !== 19) {
        return false;
    }
       
    if (! $person->hasValidId()) {
        return false;
    }
    
    return true;
}

Codor.Syntax.NullCoalescing

如果一行包含可以转换为空合并操作符的三元运算符,则产生错误。

$username = isset($customer['name']) ? $customer['name'] : 'nobody';

$username = $customer['name'] ?? 'nobody';

Codor.Syntax.LinesAfterMethod

只允许函数/方法之间有1行。超过1行将产生错误。

public function foo()
{
    //
}


public function bar()
{
    //
}

public function foo()
{
    //
}

public function bar()
{
    //
}

Codor.TypeHints.MixedReturnType

阻止您在文档块中返回mixed类型。

/**
 * @return mixed
 */
public function foo()
{
    //
}

/**
 * @return string
 */
public function foo()
{
    //
}

自定义sniffs

一些嗅探规则可以根据您的喜好进行自定义。例如,如果您希望 Codor.Files.FunctionLength 确保您的函数行数不超过30行而不是20行,您可以这样做。以下是一个带有该自定义的 codor.xml 文件示例

<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="Project">
    <description>Project Coding Standard</description>

    <rule ref="vendor/bmitch/codor/src/Codor/ruleset.xml"/>
	<rule ref="Codor.Files.FunctionLength">
		<properties>
			<property name="maxLength" value="30"/>
		</properties>
	</rule>
</ruleset>

可用的自定义

  • Codor.Files.FunctionLength
  • maxLength:一个函数/方法可以拥有的最大行数(默认 = 20)。
  • Codor.Files.FunctionParameter
  • maxParameters:一个函数/方法可以拥有的最大参数数(默认 = 3)。
  • Codor.Classes.ClassLength
  • maxLength:一个类可以拥有的最大行数(默认 = 200)。
  • Codor.Files.IndentationLevel
  • indentationLimit:缩进数不能超过或等于这个数值(默认 = 2)。

类似包

贡献

请参阅 CONTRIBUTING.md

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件