symplify / phpstan-rules
一套用于 PHPStan 的 Symplify 规则
Requires
- php: ^7.2|^8.0
- nette/utils: ^3.2.9 || ^4.0
- phpstan/phpstan: ^1.10.30
- webmozart/assert: ^1.11
- dev-main
- 13.0.1
- 13.0.0
- 12.7.0
- 12.6.4
- 12.6.3
- 12.6.2
- 12.6.1
- 12.6.0
- 12.5.2
- 12.5.1
- 12.5.0
- 12.4.9
- 12.4.8
- 12.4.7
- 12.4.6
- 12.4.5
- 12.4.4
- 12.4.3
- 12.4.2
- 12.4.1
- 12.4.0
- 12.3.1
- 12.3.0.72
- 12.3.0
- 12.2.7.72
- 12.2.7
- 12.2.6.72
- 12.2.6
- 12.2.5.72
- 12.2.5
- 12.2.4.72
- 12.2.4
- 12.2.3.72
- 12.2.3
- 12.2.2.72
- 12.2.2
- 12.2.1.72
- 12.2.1
- 12.2.0.72
- 12.2.0
- 12.1.4.72
- 12.1.4
- 12.1.3.72
- 12.1.3
- 12.1.2.72
- 12.1.2
- 12.1.1.72
- 12.1.1
- 12.1.0.72
- 12.1.0
- 12.0.4.72
- 12.0.4
- 12.0.3.72
- 12.0.3
- 12.0.2.72
- 12.0.2
- 12.0.1.72
- 12.0.1
- 12.0.0.72
- 12.0.0
- 11.4.1.72
- 11.4.1
- 11.4.0.72
- 11.4.0
- 11.3.5.72
- 11.3.5
- 11.3.4.72
- 11.3.4
- 11.3.3.72
- 11.3.3
- 11.3.2.72
- 11.3.2
- 11.3.1.72
- 11.3.1
- 11.3.0.72
- 11.3.0
- 11.2.5.72
- 11.2.5
- 11.2.4.72
- 11.2.4
- 11.2.3.72
- 11.2.3
- 11.2.2.72
- 11.2.2
- 11.2.1
- 11.2.0.72
- 11.2.0
- 11.1.28.72
- 11.1.28
- 11.1.27.72
- 11.1.27
- 11.1.26.72
- 11.1.26
- 11.1.25.72
- 11.1.25
- 11.1.24
- 11.1.23
- 11.1.22
- 11.1.21
- 11.1.20
- 11.1.19
- 11.1.18
- 11.1.17
- 11.1.16
- 11.1.15
- 11.1.14
- 11.1.13
- 11.1.12
- 11.1.11
- 11.1.10
- 11.1.9
- 11.1.8
- 11.1.7
- 11.1.6
- 11.1.5
- 11.1.4
- 11.1.1
- 11.1.0
- 11.0.9
- 11.0.8
- 11.0.7
- 11.0.6
- 11.0.5
- 11.0.4
- 11.0.3
- 11.0.2
- 11.0.1
- 11.0.0
- 10.3.3
- 10.3.2
- 10.3.1
- 10.3.0
- 10.2.11
- 10.2.10
- 10.2.9
- 10.2.8
- 10.2.7
- 10.2.6
- 10.2.5
- 10.2.4
- 10.2.3
- 10.2.2
- 10.2.1
- 10.2.0
- 10.1.4
- 10.1.3
- 10.1.2
- 10.1.1
- 10.1.0
- 10.0.25
- 10.0.24
- 10.0.23
- 10.0.22
- 10.0.21
- 10.0.20
- 10.0.19
- 10.0.18
- 10.0.17
- 10.0.16
- 10.0.15
- 10.0.14
- 10.0.13
- 10.0.12
- 10.0.11
- 10.0.10
- 10.0.9
- 10.0.8
- 10.0.7
- 10.0.6
- 10.0.5
- 10.0.4
- 10.0.3
- 10.0.2
- 10.0.1
- 10.0.0
- 10.0.0-beta17
- 10.0.0-beta16
- 10.0.0-beta15
- 10.0.0-beta14
- 10.0.0-beta13
- 10.0.0-beta12
- 10.0.0-beta11
- 10.0.0-beta10
- 10.0.0-beta9
- 10.0.0-beta8
- 10.0.0-beta7
- 10.0.0-beta6
- 10.0.0-beta5
- 10.0.0-beta4
- 10.0.0-beta3
- 10.0.0-beta2
- 10.0.0-beta1
- 9.4.70
- 9.4.69
- 9.4.68
- 9.4.67
- 9.4.66
- 9.4.65
- 9.4.64
- 9.4.63
- 9.4.62
- 9.4.61
- 9.4.60
- 9.4.59
- 9.4.58
- 9.4.57
- 9.4.56
- 9.4.55
- 9.4.54
- 9.4.53
- 9.4.52
- 9.4.51
- 9.4.50
- 9.4.49
- 9.4.48
- 9.4.47
- 9.4.46
- 9.4.45
- 9.4.44
- 9.4.43
- 9.4.42
- 9.4.41
- 9.4.40
- 9.4.39
- 9.4.38
- 9.4.37
- 9.4.36
- 9.4.35
- 9.4.34
- 9.4.33
- 9.4.32
- 9.4.31
- 9.4.30
- 9.4.29
- 9.4.28
- 9.4.27
- 9.4.26
- 9.4.25
- 9.4.24
- 9.4.23
- 9.4.22
- 9.4.21
- 9.4.20
- 9.4.19
- 9.4.18
- 9.4.17
- 9.4.16
- 9.4.15
- 9.4.14
- 9.4.13
- 9.4.12
- 9.4.11
- 9.4.10
- 9.4.9
- 9.4.8
- 9.4.7
- 9.4.6
- 9.4.5
- 9.4.4
- 9.4.3
- 9.4.2
- v9.4.1
- v9.4.0
- v9.3.27
- v9.3.26
- v9.3.25
- v9.3.24
- v9.3.23
- v9.3.22
- v9.3.21
- v9.3.20
- v9.3.19
- v9.3.18
- v9.3.17
- v9.3.16
- v9.3.15
- v9.3.14
- v9.3.13
- v9.3.12
- v9.3.11
- v9.3.10
- v9.3.8
- v9.3.6
- v9.3.5
- v9.3.4
- v9.3.3
- v9.3.1
- v9.3.0
- v9.2.24
- v9.2.23
- v9.2.22
- v9.2.21
- v9.2.20
- v9.2.19
- v9.2.18
- v9.2.17
- v9.2.16
- v9.2.15
- v9.2.14
- v9.2.13
- v9.2.12
- v9.2.11
- v9.2.10
- v9.2.9
- v9.2.8
- v9.2.7
- v9.2.6
- v9.2.5
- v9.2.4
- v9.2.3
- v9.2.2
- 9.2.1
- 9.2.0
- 9.1.9
- 9.1.8
- 9.1.7
- 9.1.6
- 9.1.5
- 9.1.4
- 9.1.3
- 9.1.1
- 9.1.0
- 9.0.50
- 9.0.49
- 9.0.48
- 9.0.47
- 9.0.46
- 9.0.45
- 9.0.44
- 9.0.43
- 9.0.42
- 9.0.41
- 9.0.40
- 9.0.39
- 9.0.38
- 9.0.37
- 9.0.36
- 9.0.35
- 9.0.34
- 9.0.33
- 9.0.32
- 9.0.31
- 9.0.30
- 9.0.29
- 9.0.28
- 9.0.27
- 9.0.26
- 9.0.25
- 9.0.24
- 9.0.23
- 9.0.22
- 9.0.21
- 9.0.20
- 9.0.19
- 9.0.18
- 9.0.17
- 9.0.16
- 9.0.15
- 9.0.14
- 9.0.13
- 9.0.12
- 9.0.11
- 9.0.10
- 9.0.9
- 9.0.8
- 9.0.7
- 9.0.6
- 9.0.5
- 9.0.4
- 9.0.3
- 9.0.2
- 9.0.1
- 9.0.0
- 9.0.0-rc1
- 9.0.0-BETA9
- 9.0.0-BETA8
- 9.0.0-BETA7
- 9.0.0-BETA6
- 9.0.0-BETA5
- 9.0.0-BETA4
- 9.0.0-BETA3
- 9.0.0-BETA2
- 9.0.0-BETA1
- 8.3.48
This package is auto-updated.
Last update: 2024-09-16 20:28:44 UTC
README
用于 Symplify 项目的 PHPStan 规则集
- 查看 规则概览
安装
composer require symplify/phpstan-rules --dev
注意:请确保使用 phpstan/extension-installer
加载必要的服务配置。
1. 添加准备好的规则集
规则集是一组按共同区域分组(例如改进命名)的规则。您可以从中选择 5 个规则集。
includes: - vendor/symplify/phpstan-rules/config/code-complexity-rules.neon - vendor/symplify/phpstan-rules/config/naming-rules.neon - vendor/symplify/phpstan-rules/config/regex-rules.neon - vendor/symplify/phpstan-rules/config/static-rules.neon
逐个添加规则集,修复您认为有用的,忽略其余部分。
您是否编写自定义 Rector 规则?也为它们添加规则。
includes: - vendor/symplify/phpstan-rules/config/rector-rules.neon
2. 挑选可配置的规则
有一个包含预配置的可配置规则的规则集。包含它并查看发现了哪些错误
# phpstan.neon includes: - vendor/symplify/phpstan-rules/config/configurable-rules.neon
您想 根据您的口味定制它 吗?选择一个 PHPStan 规则并手动配置它 ↓
services: - class: Symplify\PHPStanRules\Rules\ForbiddenNodeRule tags: [phpstan.rules.rule] arguments: forbiddenNodes: - PhpParser\Node\Expr\Empty_ - PhpParser\Node\Stmt\Switch_
3. 注册特定规则
30 规则概览
AnnotateRegexClassConstWithRegexLinkRule
添加一个链接到 regex101.com,显示实际的正则表达式,以便在将来出现错误/扩展时更容易维护
class SomeClass { private const COMPLICATED_REGEX = '#some_complicated_stu|ff#'; }
❌
class SomeClass { /** * @see https://regex101.com/r/SZr0X5/12 */ private const COMPLICATED_REGEX = '#some_complicated_stu|ff#'; }
👍
CheckClassNamespaceFollowPsr4Rule
类命名空间 "%s" 不遵循 composer.json
中的 PSR-4 配置
// defined "Foo\Bar" namespace in composer.json > autoload > psr-4 namespace Foo; class Baz { }
❌
// defined "Foo\Bar" namespace in composer.json > autoload > psr-4 namespace Foo\Bar; class Baz { }
👍
CheckRequiredInterfaceInContractNamespaceRule
接口必须位于 "Contract" 或 "Contracts" 命名空间
namespace App\Repository; interface ProductRepositoryInterface { }
❌
namespace App\Contract\Repository; interface ProductRepositoryInterface { }
👍
ClassNameRespectsParentSuffixRule
类应该有后缀 "%s" 以尊重父类型
🔧 配置它!
services: - class: Symplify\PHPStanRules\Rules\ClassNameRespectsParentSuffixRule tags: [phpstan.rules.rule] arguments: parentClasses: - Symfony\Component\Console\Command\Command
↓
class Some extends Command { }
❌
class SomeCommand extends Command { }
👍
ExplicitClassPrefixSuffixRule
接口后缀为 "Interface",trait 后缀为 "Trait" 独占
<?php interface NotSuffixed { } trait NotSuffixed { } abstract class NotPrefixedClass { }
❌
<?php interface SuffixedInterface { } trait SuffixedTrait { } abstract class AbstractClass { }
👍
ForbiddenArrayMethodCallRule
不允许使用数组方法调用 [$this, "method"]。使用显式方法代替以帮助 PhpStorm、PHPStan 和 Rector 理解您的代码
usort($items, [$this, "method"]);
❌
usort($items, function (array $apples) { return $this->method($apples); };
👍
ForbiddenExtendOfNonAbstractClassRule
只能扩展抽象类
final class SomeClass extends ParentClass { } class ParentClass { }
❌
final class SomeClass extends ParentClass { } abstract class ParentClass { }
👍
ForbiddenFuncCallRule
函数 "%s()"
不能在代码中使用/保留
🔧 配置它!
services: - class: Symplify\PHPStanRules\Rules\ForbiddenFuncCallRule tags: [phpstan.rules.rule] arguments: forbiddenFunctions: - eval
↓
echo eval('...');
❌
echo '...';
👍
services: - class: Symplify\PHPStanRules\Rules\ForbiddenFuncCallRule tags: [phpstan.rules.rule] arguments: forbiddenFunctions: dump: 'seems you missed some debugging function'
↓
dump($value); echo $value;
❌
echo $value;
👍
禁止在一个文件中定义多个类
单个文件中不允许定义多个类/接口/特质
// src/SomeClass.php class SomeClass { } interface SomeInterface { }
❌
// src/SomeClass.php class SomeClass { } // src/SomeInterface.php interface SomeInterface { }
👍
禁止使用节点规则
"%s" 被禁止使用
🔧 配置它!
services: - class: Symplify\PHPStanRules\Rules\ForbiddenNodeRule tags: [phpstan.rules.rule] arguments: forbiddenNodes: - PhpParser\Node\Expr\ErrorSuppress
↓
return @strlen('...');
❌
return strlen('...');
👍
禁止静态类常量获取规则
避免静态访问常量,因为它们可能会改变值。使用接口和契约方法代替
class SomeClass { public function run() { return static::SOME_CONST; } }
❌
class SomeClass { public function run() { return self::SOME_CONST; } }
👍
不允许动态名称规则
使用显式名称而不是动态名称
class SomeClass { public function old(): bool { return $this->${variable}; } }
❌
class SomeClass { public function old(): bool { return $this->specificMethodName(); } }
👍
不允许实体在实体命名空间外
带有 #[Entity] 属性的类必须位于 "Entity" 命名空间中,以便 Doctrine 加载
namespace App\ValueObject; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Product { }
❌
namespace App\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Product { }
👍
不允许全局常量规则
全局常量被禁止。使用类似枚举的类列表代替
const SOME_GLOBAL_CONST = 'value';
❌
class SomeClass { public function run() { return self::SOME_CONST; } }
👍
不允许内联字符串正则表达式规则
使用本地命名常量而不是内联字符串作为正则表达式,通过常量名称解释含义
class SomeClass { public function run($value) { return preg_match('#some_stu|ff#', $value); } }
❌
class SomeClass { /** * @var string */ public const SOME_STUFF_REGEX = '#some_stu|ff#'; public function run($value) { return preg_match(self::SOME_STUFF_REGEX, $value); } }
👍
不允许引用规则
使用显式返回值而不是魔法引用
class SomeClass { public function run(&$value) { } }
❌
class SomeClass { public function run($value) { return $value; } }
👍
不允许返回数组变量列表规则
使用值对象而不是返回值
class ReturnVariables { public function run($value, $value2): array { return [$value, $value2]; } }
❌
final class ReturnVariables { public function run($value, $value2): ValueObject { return new ValueObject($value, $value2); } }
👍
不允许返回设置器方法规则
设置器方法不能返回任何内容,只能设置值
final class SomeClass { private $name; public function setName(string $name): int { return 1000; } }
❌
final class SomeClass { private $name; public function setName(string $name): void { $this->name = $name; } }
👍
不允许单接口实现者规则
接口 "%s" 只有一个实现者。考虑直接使用类,因为使用接口没有意义。
class SomeClass implements SomeInterface { } interface SomeInterface { }
❌
class SomeClass implements SomeInterface { } class AnotherClass implements SomeInterface { } interface SomeInterface { }
👍
不允许测试模拟规则
禁止模拟 "%s" 类。为了更好的静态分析,使用直接/匿名类代替
use PHPUnit\Framework\TestCase; final class SkipApiMock extends TestCase { public function test() { $someTypeMock = $this->createMock(SomeType::class); } }
❌
use PHPUnit\Framework\TestCase; final class SkipApiMock extends TestCase { public function test() { $someTypeMock = new class() implements SomeType {}; } }
👍
首选类规则
使用 "%s" 类/接口而不是 "%s"
🔧 配置它!
services: - class: Symplify\PHPStanRules\Rules\PreferredClassRule tags: [phpstan.rules.rule] arguments: oldToPreferredClasses: SplFileInfo: CustomFileInfo
↓
class SomeClass { public function run() { return new SplFileInfo('...'); } }
❌
class SomeClass { public function run() { return new CustomFileInfo('...'); } }
👍
防止父方法可见性覆盖规则
将 "%s()"
方法的可见性更改为 "%s",以尊重父方法的可见性。
class SomeParentClass { public function run() { } } class SomeClass extends SomeParentClass { protected function run() { } }
❌
class SomeParentClass { public function run() { } } class SomeClass extends SomeParentClass { public function run() { } }
👍
正则常量后缀规则
使用 "_REGEX" 后缀命名常量,而不是 "%s"
class SomeClass { public const SOME_NAME = '#some\s+name#'; public function run($value) { $somePath = preg_match(self::SOME_NAME, $value); } }
❌
class SomeClass { public const SOME_NAME_REGEX = '#some\s+name#'; public function run($value) { $somePath = preg_match(self::SOME_NAME_REGEX, $value); } }
👍
RequireAttributeNameRule
属性必须显式定义所有名称
use Symfony\Component\Routing\Annotation\Route; class SomeController { #[Route("/path")] public function someAction() { } }
❌
use Symfony\Component\Routing\Annotation\Route; class SomeController { #[Route(path: "/path")] public function someAction() { } }
👍
RequireAttributeNamespaceRule
属性必须位于 "Attribute" 命名空间
// app/Entity/SomeAttribute.php namespace App\Controller; #[\Attribute] final class SomeAttribute { }
❌
// app/Attribute/SomeAttribute.php namespace App\Attribute; #[\Attribute] final class SomeAttribute { }
👍
RequireExceptionNamespaceRule
Exception
必须位于 "Exception" 命名空间
// app/Controller/SomeException.php namespace App\Controller; final class SomeException extends Exception { }
❌
// app/Exception/SomeException.php namespace App\Exception; final class SomeException extends Exception { }
👍
RequireInvokableControllerRule
使用具有 __invoke()
方法的可调用控制器,而不是命名动作方法
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; final class SomeController extends AbstractController { #[Route()] public function someMethod() { } }
❌
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; final class SomeController extends AbstractController { #[Route()] public function __invoke() { } }
👍
RequireUniqueEnumConstantRule
枚举常量 "%s" 重复。请使它们唯一
use MyCLabs\Enum\Enum; class SomeClass extends Enum { private const YES = 'yes'; private const NO = 'yes'; }
❌
use MyCLabs\Enum\Enum; class SomeClass extends Enum { private const YES = 'yes'; private const NO = 'no'; }
👍
SeeAnnotationToTestRule
类 "%s" 缺少包含测试用例类引用的 @see
注解
🔧 配置它!
services: - class: Symplify\PHPStanRules\Rules\SeeAnnotationToTestRule tags: [phpstan.rules.rule] arguments: requiredSeeTypes: - Rule
↓
class SomeClass extends Rule { }
❌
/** * @see SomeClassTest */ class SomeClass extends Rule { }
👍
UppercaseConstantRule
常量 "%s" 必须为大写
final class SomeClass { public const some = 'value'; }
❌
final class SomeClass { public const SOME = 'value'; }
👍
快乐编码!