efabrica/phpstan-rules

0.7.1 2024-02-27 11:40 UTC

README

PHPStan 扩展,提供多个服务和规则,以帮助您在应用程序中找到错误。

PHP unit PHPStan level PHP static analysis Latest Stable Version Total Downloads

安装

要使用此扩展,请在 Composer 中要求它

composer require --dev efabrica/phpstan-rules

设置

此扩展添加了多个规则。您可以通过在您的 phpstan.neon 文件中包含以下文件来使用它们全部:

includes:
    - vendor/efabrica/phpstan-rules/extension.neon
    - vendor/efabrica/phpstan-rules/rules.neon

或者只包含

includes:
    - vendor/efabrica/phpstan-rules/extension.neon

然后选择您要使用的规则

Guzzle - ClientCallWithoutOptionRule

查找所有没有某些选项(例如 timeout、connect_timeout)的 GuzzleHttp\Client 方法的调用

services:
    -
        factory: Efabrica\PHPStanRules\Rule\Guzzle\ClientCallWithoutOptionRule(['timeout', 'connect_timeout'])
        tags:
            - phpstan.rules.rule
use GuzzleHttp\Client;

$guzzleClient = new Client();
$guzzleClient->request('GET', 'https://example.com/api/url');

use GuzzleHttp\Client;

$guzzleClient = new Client();
$guzzleClient->request('GET', 'https://example.com/api/url', ['timeout' => 3, 'connect_timeout' => 1]);

👍

Tomaj/Nette API - InputParamNameRule

检查所有输入参数的名称。每个名称必须只包含字母数字字符和 _

services:  
    -
        factory: Efabrica\PHPStanRules\Rule\Tomaj\NetteApi\InputParamNameRule
        tags:
            - phpstan.rules.rule
use Tomaj\NetteApi\Handlers\BaseHandler;

final class SomeHandler extends BaseHandler
{
    public function params(): array
    {
        return [
            new GetInputParam('my-name')
        ];
    }
}

use Tomaj\NetteApi\Handlers\BaseHandler;

final class SomeHandler extends BaseHandler
{
    public function params(): array
    {
        return [
            new GetInputParam('my_name')
        ];
    }
}

👍

检查 trait 上下文 - TraitContextRule

检查是否只在通过注释 @context {Type} 指定的类上下文中使用 trait

services:  
    -
        factory: Efabrica\PHPStanRules\Rule\General\TraitContextRule
        tags:
            - phpstan.rules.rule
/**
 * @context MyInterface
 */
trait MyTrait
{

}

final class SomeClass
{
    use MyTrait;
}

/**
 * @context MyInterface
 */
trait MyTrait
{

}

final class SomeClass implements MyInterface
{
    use MyTrait;
}

👍

检查对象方法中的调用方法

检查某些方法是否未在禁用上下文中使用 - 特定对象的特定方法。

parameters:
    disabledMethodCalls:
        -
            context: 'WithCallInterface::checkedMethod'
            disabled: 'ClassWithDisabledMethod::disabledMethod'

services:
    -
        factory: Efabrica\PHPStanRules\Rule\General\DisableMethodCallInContextRule(%disabledMethodCalls%)
        tags:
            - phpstan.rules.rule
class ClassWithDisabledMethod implements WithDisabledMethodInterface
{
    public function disabledMethod() {} // this method shouldn't be called in WithCallInterface::checkedMethod
}
final class SomeClass implements WithCallInterface
{
    public function checkedMethod(): array
    {
        return [(new ClassWithDisabledMethod)->disabledMethod()]
    }
}

final class SomeClass implements WithCallInterface
{
    public function checkedMethod(): array
    {
        return [(new ClassWithDisabledMethod)]
    }
}

👍

检查带有必需参数的调用方法

检查是否以相应的类型使用所有必需参数调用某些方法。

parameters:
    requiredParametersInMethodCalls:
        -
            context: 'SomeClass::someMethod'
            parameters:
                -
                    name: someParameter
                    type: string
                    tip: 'Always use parameter someParameter as string because...'

services:
    -
        factory: Efabrica\PHPStanRules\Rule\General\RequiredParametersInMethodCallRule(%requiredParametersInMethodCalls%)
        tags:
            - phpstan.rules.rule
class SomeClass
{
    public function someMethod(?string $someParameter = null): void
    {
        // this method should be called with string value of $someParameter
    }
}
class Foo
{
    public function bar(SomeClass $someClass)
    {
        $someClass->someMethod();
    }
}

class Foo
{
    public function bar(SomeClass $someClass)
    {
        $someClass->someMethod('baz');
    }
}

👍

不要连接已翻译的字符串

每种语言都有自己的句子词序,我们无法在所有语言中使用例如变量在相同的位置。在翻译库中(例如 symfony/translator)存在机制 - 我们可以使用占位符如 %name% 等。此规则检查您是否使用翻译的消息,然后将其与某些其他字符串连接。

parameters:
    translateCalls:
        - iAmTranslateFunction
        - Efabrica\PHPStanRules\Tests\Rule\General\DisabledConcatenationWithTranslatedStringsRule\Source\TranslatorInterface::iAmTranslateMethod
        - Efabrica\PHPStanRules\Tests\Rule\General\DisabledConcatenationWithTranslatedStringsRule\Source\TranslatorInterface::iAmTranslateStaticMethod
    allowedTranslateConcatenationPatterns:
        - '[\s]*<.*?>[\s]*<\/.*?>[\s]*'
        - '[\s]*This is allowed text[\s]*'
        - '[\s]*\#[0-9]+[\s]*'

services:
    -
        factory: Efabrica\PHPStanRules\Rule\General\DisabledConcatenationWithTranslatedStringsRule(%translateCalls%)
        tags:
            - phpstan.rules.rule
$message = 'Hello';
$name = 'Mark';
echo $translator->iAmTranslateMethod($message) . ' ' . $name;

$message = 'Hello %name%';
$name = 'Mark';
echo $translator->iAmTranslateMethod($message, ['name' => $name];

👍

禁止的构造函数参数类型

此规则检查构造函数是否包含禁止的参数类型。

parameters:
    forbiddenConstructorParametersTypes:
        -
            context: 'SomeClass'
            forbiddenTypes:
                -
                    type: ForbiddenType
                    tip: 'ForbiddenType is not allowed, use NotForbiddenType instead'

services:
    -
        factory: Efabrica\PHPStanRules\Rule\General\ForbiddenConstructorParametersTypesRule(%forbiddenConstructorParametersTypes%)
        tags:
            - phpstan.rules.rule
class SomeClass
{

}

class ForbiddenType
{

}

class NotForbiddenType
{

}
class Foo extends SomeClass
{
    public function __construct(ForbiddenType $type)
    {
    
    }
}

class Foo extends SomeClass
{
    public function __construct(NotForbiddenType $type)
    {
    
    }
}

👍

性能 - DisabledCallsInLoopsRule

不建议在循环中调用某些函数。例如 array_merge。

services:
    -
        factory: Efabrica\PHPStanRules\Rule\Performance\DisabledCallsInLoopsRule
        tags:
            - phpstan.rules.rule
$result = [];
for ($i = 0; $i < 100; $i++) {
    $result = array_merge($result, $data[$i]);
}

$result = array_merge([], ...$data);

👍