bestit / php_codesniffer
Requires
- php: >=8.0
- slevomat/coding-standard: ^8.0
Requires (Dev)
- best-it/license-check: ^0.1.0
- captainhook/plugin-composer: ^5.3
- infection/infection: ^0.21.5
- pdepend/pdepend: 2.8.*
- phpcompatibility/php-compatibility: ^9.3
- phploc/phploc: ^7.0.2
- phpmd/phpmd: ^2.6
- phpunit/phpunit: ^9.3
- sebastian/phpcpd: ^6.0.3
Suggests
- phpcompatibility/php-compatibility: If you want to check for php version compatibility. Please use at least ^9.0.
- dev-main
- 4.0.0
- 4.0.0-RC2
- 4.0.0-RC1
- 3.x-dev
- 3.5.0
- 3.5.0-RC2
- 3.5.0-RC1
- 3.4.1
- 3.4.0
- 3.3.1
- 3.3.0
- 3.2.0
- 3.1.1
- 3.1.0
- 3.0.0
- 2.x-dev
- 2.1.0
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.x-dev
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.x-dev
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- 0.11.0
- 0.10.1
- 0.10.0
- 0.9.1
- 0.9.0
- 0.8.0
- 0.7.0
- 0.6.0
- 0.5.0
- 0.4.0
- 0.3.1
- 0.3.0
- 0.2.0
- 0.1.0
- dev-hook-test
- dev-feature/PHPCS-247-start-php-8
- dev-feature/DEVHEADS-60-phpstan-integration
- dev-release/2.1.0
- dev-release/1.3.0
- dev-bugfix/PHPCS-198-php-compatibility-php_version_check
- dev-feature/PHPCS-139-cache-files
- dev-feature/PHPCS-148-Identical
- dev-bugfix/PHPCS-139-find-memory-leaks
This package is auto-updated.
Last update: 2023-04-13 09:32:58 UTC
README
此包包含默认规则集和用于所有 best it 项目的自定义规则。
安装
可以使用以下命令使用 composer 安装我们的 PHP_CodeSniffer 包
composer require best-it/php_codesniffer --dev
请使用版本 1 用于 PHP 7.0!
使用方法
创建一个 PHP_CodeSniffer 配置(phpcs.xml.dist / phpcs.xml)如下所示
<?xml version="1.0"?> <ruleset name="PROJECT-X"> <description>The coding standard for project x.</description> <!-- Path to best it ruleset. --> <rule ref="./vendor/best-it/php_codesniffer/src/Standards/BestIt/ruleset.xml" /> <!-- Path to directory which are checked. --> <file>src/</file> <file>tests/</file> </ruleset>
如果您想针对特殊的 PHP 版本进行嗅探,只需声明一个 "testVersion" 如下所示
<config name="testVersion" value="7.1" />
并在包含我们的规则集后包含
<rule ref="PHPCompatibility" />
(不要忘记 dev-require phpcompatibility/php-compatibility:^9.0。)
执行 PHP_CodeSniffer(路径可能因您的 composer 配置而异)
./vendor/bin/phpcs
我们使用警告来标记人类应该检查但不应导致自动构建失败的事情。如果您想看到警告但得到成功的构建,请使用特殊配置选项 ignore_warnings_on_exit
./vendor/bin/phpcs --config-set ignore_warnings_on_exit 1
或者,如果您只想为单次运行启用此选项
./vendor/bin/phpcs --runtime-set ignore_warnings_on_exit 1
如果您想完全忽略警告,可以提供 cli 参数 n
./vendor/bin/phpcs -n
我们建议不要忽略警告,而只是在手动拉取/合并请求时进行检查。
在 PHPStorm 中使用
如何在我们的最爱 IDE 中使用它?
/File/Settings
使用的嗅探器
BestIt 标准的基础是 PSR-12。
嗅探器 | 描述 | 可抑制 |
---|---|---|
BestIt.Classes.ModernClassNameReference.ClassNameReferencedViaFunctionCall | 您必须使用 ::class 而不是函数。 | 否 |
BestIt.Classes.ModernClassNameReference.ClassNameReferencedViaMagicConstant | 您必须使用 ::class 而不是 CLASS。 | 否 |
BestIt.Commenting.ClassDoc.DocCommentUcFirst | 每个文档注释块应该以 ucfirst 开头。 | 否 |
BestIt.Commenting.ClassDoc.NoLineAfterDocComment | 每个文档注释块(摘要或长描述段落)应该以双行结尾。 | 否 |
BestIt.Commenting.ClassDoc.NoSummary | 必须有一个摘要。 | 否 |
BestIt.Commenting.ClassDoc.SummaryTooLong | 摘要应该在一行内。 | 否 |
BestIt.Commenting.ConstantDoc.DocCommentUcFirst | 每个文档注释块应该以 ucfirst 开头。 | 否 |
BestIt.Commenting.ConstantDoc.NoLineAfterDocComment | 每个文档注释块(摘要或长描述段落)应该以双行结尾。 | 否 |
BestIt.Commenting.ConstantDoc.NoSummary | 必须有一个摘要。 | 否 |
BestIt.Commenting.ConstantDoc.SummaryTooLong | 摘要应该在一行内。 | 否 |
BestIt.Commenting.EmptyLinesDoc.EmptyLinesFound | 文档块中不得有冗余行。 | 否 |
BestIt.Commenting.FunctionDoc.DocCommentUcFirst | 每个文档注释块应该以 ucfirst 开头。 | 否 |
BestIt.Commenting.FunctionDoc.NoLineAfterDocComment | 每个文档注释块(摘要或长描述段落)应该以双行结尾。 | 否 |
BestIt.Commenting.FunctionDoc.NoSummary | 必须有一个摘要。 | 否 |
BestIt.Commenting.FunctionDoc.SummaryTooLong | 摘要应该在一行内。 | 否 |
BestIt.Commenting.PropertyDoc.DocCommentUcFirst | 每个文档注释块应该以 ucfirst 开头。 | 否 |
BestIt.Commenting.PropertyDoc.NoLineAfterDocComment | 每个文档注释块(摘要或长描述段落)应该以双行结尾。 | 否 |
BestIt.Commenting.PropertyDoc.NoSummary | 必须有一个摘要。 | 否 |
BestIt.Commenting.PropertyDoc.SummaryTooLong | 摘要应该在一行内。 | 否 |
BestIt.Commenting.RedundantWhitespace.RedundantWhitespace | 文档标签周围不得有额外的空格。 | 否 |
BestIt.Comparisons.EmptyArrayForComparison.EmptyArray | 您不得创建空数组以检查空数组。 | 否 |
BestIt.Comparisons.EqualOperator.EqualOperatorFound | 您必须使用 "Identical" 操作符 (===)。 | 是 |
BestIt.Comparisons.ParasOfNegativeInstanceOf.ParasAroundNegativeInstanceOfMissing | 您必须提供负instanceof检查的括号。 | 否 |
BestIt.DocTags.AuthorTag.TagContentFormatInvalid | 您必须对您的代码负责,并添加一个作者标签。 | 否 |
BestIt.DocTags.DeprecatedTag.MissingDates | 缺少日期的错误代码。 | 否 |
BestIt.DocTags.DeprecatedTag.TagContentFormatInvalid | 如果您提供了已弃用的标签,您必须提供自何时弃用以及何时删除的信息。 | 否 |
BestIt.DocTags.DisallowedClassTags.TagNotAllowed | 您必须在文档注释中避免使用禁止的标签之一。 | 否 |
BestIt.DocTags.DisallowedConstantTags.TagNotAllowed | 您必须在文档注释中避免使用禁止的标签之一。 | 否 |
BestIt.DocTags.DisallowedMethodTags.TagNotAllowed | 您必须在文档注释中避免使用禁止的标签之一。 | 否 |
BestIt.DocTags.DisallowedPropertyTags.TagNotAllowed | 您必须在文档注释中避免使用禁止的标签之一。 | 否 |
BestIt.DocTags.PackageTag.TagContentFormatInvalid | 您必须提供特殊的标签格式。 | 否 |
BestIt.DocTags.PackageTag.WrongPackage | 如果有命名空间,您必须提供该命名空间作为包标签。 | 否 |
BestIt.DocTags.ParamTag.MissingDesc | 您应该为您的参数提供描述。 | 否 |
BestIt.DocTags.ParamTag.MissingType | 您必须为您的参数标签提供类型。 | 否 |
BestIt.DocTags.ParamTag.MissingVariable | 您的必须有一个与参数标签匹配的变量。 | 否 |
BestIt.DocTags.ParamTag.MissingVariables | 如果存在参数标签,您的必须提供参数。 | 否 |
BestIt.DocTags.ParamTag.MixedType | 您应该防止混合类型并尝试提供原生类型。 | 否 |
BestIt.DocTags.ParamTag.TagContentFormatInvalid | 您必须提供特殊的标签格式。 | 否 |
BestIt.DocTags.RequiredClassTags.TagOccurrenceMax | 您必须只提供所需标签的最大数量。例如,每个方法只允许一个返回值。错误记录了每个标签的具体情况。 | 否 |
BestIt.DocTags.RequiredClassTags.TagOccurrenceMin | 您必须提供所需标签。错误记录了每个标签的具体情况。 | 否 |
BestIt.DocTags.RequiredMethodTags.TagOccurrenceMax | 您必须只提供所需标签的最大数量。例如,每个方法只允许一个返回值。错误记录了每个标签的具体情况。 | 否 |
BestIt.DocTags.RequiredMethodTags.TagOccurrenceMin | 您必须提供所需标签。错误记录了每个标签的具体情况。 | 否 |
BestIt.DocTags.RequiredPropertyTags.TagOccurrenceMax | 您必须只提供所需标签的最大数量。例如,每个方法只允许一个返回值。错误记录了每个标签的具体情况。 | 否 |
BestIt.DocTags.RequiredPropertyTags.TagOccurrenceMin | 您必须提供所需标签。错误记录了每个标签的具体情况。 | 否 |
BestIt.DocTags.TagSorting.MissingNewlineBetweenTags | 您应该使用换行符分隔标签组和最终返回值。 | 按类是yes |
BestIt.DocTags.TagSorting.WrongTagSorting | 您应该按出现频率排序标签,然后按字母顺序排序,但@return应该是最后一个。 | 按类是yes |
BestIt.DocTags.ThrowsTag.MissingThrowDescription | 您应该为您的throw标签提供描述。 | 否 |
BestIt.DocTags.ThrowsTag.TagContentFormatInvalid | 您必须提供特殊的标签格式。 | 否 |
BestIt.DocTags.VarTag.TagContentFormatInvalid | 您必须为您的var标签提供类型。 | 否 |
BestIt.DocTags.VersionTag.TagContentFormatInvalid | 如果您提供了版本标签,您必须以semver 2.0格式提供,格式为Major.Minor.Patch-Version。 | 否 |
BestIt.Formatting.AlphabeticClassContent.SortAlphabetically | 您应该按字母顺序排序您的常量、方法和属性。 | 否 |
BestIt.Formatting.AlphabeticallySortedUses.IncorrectlyOrderedUses | 您必须按字母顺序提供您的导入,与PSR-12兼容。 | 否 |
(BestIt.Formatting.NoWhitespaceAfterClassOpening.IncorrectEmptyLinesAfterOpeningBrace | 在开括号之后不得有行。 | 否 |
(BestIt.Formatting.NoWhitespaceAfterClassOpening.IncorrectEmptyLinesBeforeClosingBrace | 在闭括号之前不得有行。 | 否 |
BestIt.Formatting.OpenTag.LineNotEmpty | 在打开标签后的下一行必须为空。 | 否 |
BestIt.Formatting.OpenTag.NoSpaceAfterOpenTag | 在打开标签之后必须有空白。 | 否 |
BestIt.Formatting.OpenTag.OpenTagNotFirstStatement | 在打开标签之后必须有一个空行。 | 否 |
BestIt.Formatting.ReturnTypeHintSpacingSniff.NoSpaceBetweenColonAndTypeHint | 在返回类型冒号之后不得有空格。 | |
BestIt.Formatting.ReturnTypeHintSpacingSniff.WhitespaceBeforeColon | 在返回类型冒号之前不得有空格。 | |
BestIt.Formatting.TrailingArrayComma.MissingTrailingComma | 您必须在多行数组中添加尾随逗号。 | 否 |
BestIt.Formatting.TrailingCommaInDeclaration.MissingTrailingComma | 在存在换行的情况下,强制在方法声明中添加尾随逗号。 | 否 |
BestIt.Formatting.TraitUseDeclaration.MultipleTraitsPerDeclaration | 您必须在类中导入特性等时,每行只提供一次"使用"。 | 否 |
BestIt.Formatting.UCVFSorting.WrongPosition | 您必须按照以下顺序对类、特质、接口等的内容进行排序:T_USE, T_CONST, T_VARIABLE, T_FUNCTION。 | 否 |
BestIt.Functions.FluentSetter.MustReturnThis | 每个设置器函数必须返回 $this,除非返回其他内容。 | 否 |
BestIt.Functions.FluentSetter.NoReturnFound | 您的方法必须包含一个返回值。 | 是 |
BestIt.Functions.ForbiddenFunctions.Discouraged | 您应该不使用 eval。 | 是 |
BestIt.Functions.ForbiddenFunctions.DiscouragedWithAlternative | 您应该不使用别名,而是使用原始函数名。 | 是 |
BestIt.Functions.MultipleReturn.MultipleReturnsFound | 您应该在每个方法中只使用一个返回值。 | 否 |
BestIt.Functions.NoNamedArguments.DisallowedNamedArgument | 您必须不使用命名参数。 | 否 |
BestIt.Functions.NoSimplePropertyMethod.ShouldUseTypedPropertyDirectly | 您应该直接使用类型属性,而不是简单的getter-/setter组合。 | 是 |
BestIt.Functions.TrailingCommaInCall.MissingTrailingComma | 您必须在多行函数调用后添加尾随逗号。 | 否 |
BestIt.NamingConventions.CamelCaseVariable.NotCamelCase | 您必须使用驼峰命名法提供变量,首字母小写。 | 是 |
BestIt.Spacing.ClassMemberSpacing.IncorrectCountOfBlankLinesBetweenMembers | 类成员必须用一行分隔。 | 否 |
BestIt.Spacing.ConstantSpacing.IncorrectCountOfBlankLinesAfterConstant | 常量必须用一行分隔。 | 否 |
BestIt.Spacing.NamespaceSpacing.IncorrectLinesCountAfterNamespace | 命名空间后必须有一行。 | 否 |
BestIt.Spacing.NamespaceSpacing.IncorrectLinesCountBeforeNamespace | 命名空间前必须有一行。 | 否 |
BestIt.Spacing.PropertySpacing.IncorrectCountOfBlankLinesAfterProperty | 属性后必须有一行。 | 否 |
BestIt.Spacing.SpaceAfterDeclare.GroupBlankLineFound | 多个声明语句应该分组,无需空白行。 | 否 |
BestIt.Spacing.SpaceAfterDeclare.MuchWhitespaceFound | 声明语句后必须只有一行。 | 否 |
BestIt.Spacing.SpaceAfterDeclare.NoWhitespaceFound | 声明语句后必须有一行空行。 | 否 |
BestIt.Spacing.SpaceAroundConcat.MissingSpaceAroundConcat | 您必须在concat-dot周围使用空格字符。 | 否 |
BestIt.Spacing.TraitUseSpacing.IncorrectLinesCountAfterLastUse | 您必须在您的最后一个特质使用后不提供额外的行。 | 否 |
BestIt.Spacing.TraitUseSpacing.IncorrectLinesCountBeforeFirstUse | 您必须在您的第一个特质使用前不提供额外的空白行。 | 否 |
BestIt.Spacing.TraitUseSpacing.IncorrectLinesCountBetweenUses | 您必须在特质使用之间不提供额外的空白行。 | 否 |
BestIt.Spacing.UseSpacing.IncorrectLinesCountAfterLastUse | 在最后一次使用后必须有一行。 | 否 |
BestIt.Spacing.UseSpacing.IncorrectLinesCountBeforeFirstUse | 在第一次使用前必须有一行。 | 否 |
BestIt.Spacing.UseSpacing.IncorrectLinesCountBetweenDifferentTypeOfUse | 不同使用之间不能有行。 | 否 |
BestIt.Spacing.UseSpacing.IncorrectLinesCountBetweenSameTypeOfUse | 相同使用之间不能有行。 | 否 |
BestIt.Strings.ConcatCalculationSniff.CalculationWithoutBrackets | 您必须用括号封装您的计算。 | 否 |
BestIt.TypeHints.ExplicitAssertions.RequiredExplicitAssertion | 使用断言而不是内联文档注释。 | 否 |
BestIt.TypeHints.PropertyTypeHint.MissingAnyTypeHint | 如果可能,必须有任何类型提示。 | 是 |
BestIt.TypeHints.PropertyTypeHint.MissingNativeTypeHint | 必须有一个原生类型提示(与文档块匹配)。 | 是 |
BestIt.TypeHints.ReturnTypeDeclaration.MissingReturnTypeHint | 每个函数或方法都必须有类型提示,如果返回注释有效。 | 是 |
BestIt.TypeHints.SuggestExplicitReturnType.MixedType | 您不应该使用混合类型,而应该使用显式原生返回类型。 | 是 |
Generic.Formatting.SpaceAfterCast | 类型转换后必须有一行空格。 | |
Generic.Arrays.DisallowLongArraySyntax | 每个数组语法都必须使用短数组语法。 | |
SlevomatCodingStandard.Classes.ClassConstantVisibility.MissingConstantVisibility | 常量必须带有可见性标记。 | |
SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName | 不能通过其FQCN使用任何类。您必须导入每个类! | |
SlevomatCodingStandard.TypeHints.DeclareStrictTypes | 每个文件都必须在开标签后有两行断行符,并包含 "declare(strict_types=1);"。等号周围不能有空格。 | |
Squiz.Strings.DoubleQuoteUsage | 每个字符串必须用单引号包裹。 |
开发
简介
代码嗅探器基于一种基于标记的嗅探机制。
您可以使用代码嗅探器 cli 的 详细选项,查看在您的文件中哪些标记被解析以及它们在文件中的位置。请参考官方代码嗅探器教程了解编写自定义嗅探器的理论。
本教程的要点是,您需要实现 PHP_CodeSniffer\Sniffs\Sniff 接口,该接口强制执行两个方法
1. 标记注册
register 方法应返回您想要嗅探的标记的解析器标记 ID。
2. 处理
当调用 process 方法时,它将带有您注册的标记在给定文件对象的标记堆栈中的位置的参数。
最佳 IT "助手"
BestIt\Sniffs\AbstractSniff
我们将基本工作重构到这个抽象类中。您可以使用扩展的 API 获取更干净的 API,并跳过简单的样板代码。
- areRequirementsMet:如果此方法返回 false,则嗅探器将被“跳过”。
- isSniffSuppressed:如果此方法返回 true,则提供了抑制注释,并且嗅探器应该被“跳过”。
- processToken:将正常 API 的样板代码保存在对象属性中,您可以在不“重新实现”基本接口及其方法参数的情况下嗅探您的标记。
- setUp:您可以在使用 areRequirementsMet 检查要求之前设置测试。
- tearDown:如果想要“销毁”此嗅探器,则可以在嗅探处理之后将其拆解。
CodeSniffer 的设计是无状态的,即使嗅探器类用作“单例”。因此,如果在嗅探器中保存状态,则必须在之后进行 tearDown 或在 setUp 中正确初始化。
BestIt\Sniffs\DocTags\AbstractTagSniff
这个抽象类可以帮助您嗅探单个文档标记。只需实现给定的抽象方法,您就可以注册并嗅探特定的文档标记,并检查其内容,直到换行符。
BestIt\Sniffs\DocTags\TagContentFormatTrait
这个特性旨在与 AbstractTagSniff 一起使用,并为您提供了一个 API,该 API 会自动将标记内容与正则表达式模式进行比较,如果出现错误或警告,则使用代码 TagContentFormatInvalid。
BestIt\Sniffs*RegistrationTrait
我们提供了一些特性,这些特性使注册类似类的结构、常量、方法和属性的嗅探器变得更容易。
测试
要求
要能够测试我们编写的嗅探器,请确保 composer 已安装并带有 --prefer-source
选项。这是必需的,因为我们使用了 SlevomatCodingStandard 的 TestCase。
错误代码作为公共常量
除了可读性和干净的代码,我们的测试基础还要求你在嗅探类中提供错误代码作为公共常量,并以前缀 CODE_ 开头。
没有 "Test" 命名空间
我们的测试基础期望你在 "正常" 命名空间中提供一切: BestIt。
帮助测试特性
令牌注册
特性 BestIt\Sniffs\TestTokenRegistrationTrait 帮助你测试已注册的令牌。
公共错误代码
特性 BestIt\Sniffs\TestRequiredConstantsTrait 帮助你测试错误代码。我们建议你也测试这些值,因为它们可能是来自你的 "客户" 的 "外部规则集" 的一部分,不受你的控制。因此,我们强制这些常量值保持 API 稳定性!
默认集成测试
特性 BestIt\Sniffs\DefaultSniffIntegrationTestTrait 提供了三个测试,用于测试基于嗅探器单独测试文件的通常用例。
- testCorrect
- testErrors
- testWarnings
要求
- 你的测试文件应与你的嗅探器完全相同(包括命名空间),但后缀为 Test。
- 提供一个名为 Fixtures 的文件夹,作为你的测试文件的同级文件夹。
- 在你的 "Fixtures" 目录中创建一个文件夹,其名称与嗅探器的简称完全相同。
testCorrect
在你的 fixtures 目录中创建一个名为 correct 的文件夹。该文件夹中的每个 PHP 文件都将与你的嗅探器进行检查。嗅探器可能不会为成功测试填充错误和警告!
testErrors
在你的 fixtures 目录中创建一个名为 with_errors 的文件夹。该文件夹中的每个 PHP 文件都应在你的嗅探器中触发错误。你必须通过文件名提供错误结构。文件名必须匹配以下 pregex
/(?P<code>[\w]+)(\(\w*\))?\.(?P<errorLines>[\d-\,]+)(?P<fixedSuffix>\.fixed)?\.php/
文件名提供了有关应发生哪些错误以及在哪一行的信息。示例文件可能是 ErrorCode.1.php, ErrorCode.1,2,3.php, ErrorCode.1,2,3.fixed.php,ErrorCode(2).1,2,3.php,ErrorCode(2).1,2,3.fixed.php_。错误代码必须是你的嗅探器的原始代码值,第一个点之后的所有数字是错误的行号。
如果你提供了一个以 "fixed" 结尾的附加文件,则这是其错误兄弟的正确格式化的文件。
testWarnings
在你的 fixtures 目录中创建一个名为 with_warnings 的文件夹。该文件夹中的每个 PHP 文件都应在你的嗅探器中触发警告。你必须通过文件名提供警告结构。文件名必须匹配以下 pregex
/(?P<code>[\w]+)(\(\w*\))?\.(?P<errorLines>[\d-\,]+)(?P<fixedSuffix>\.fixed)?\.php/
文件名提供了有关应发生哪些警告以及在哪一行的信息。示例文件可能是 WarningCode.1.php, WarningCode.1,2,3.php, WarningCode.1,2,3.fixed.php,WarningCode(2).1,2,3.php,WarningCode(2).1,2,3.fixed.php_。警告代码必须是你的嗅探器的原始代码值,第一个点之后的所有数字是带有警告的行号。
如果你提供了一个以 "fixed" 结尾的附加文件,则这是其错误兄弟的正确格式化的文件。
贡献
请参阅 CONTRIBUTING.md。
语义版本化
我们使用与我们的规则集强制执行的样式相关的语义化版本控制,而不是直接与我们的源代码相关。这意味着,我们的代码中可能存在破坏性更改,但只要样式没有发生重大变化,破坏性更改就不会反映在我们的版本号中。
- 补丁版本(最后一位数):规则集中的向后兼容的错误修复
- 次要版本(中间位数):规则集中的向后兼容的新特性(仅警告、删除或可自动修复的错误)
- 主版本(第一位数):规则集中的破坏性更改
我们优化版本控制是为了sniffer的使用,而不是为了开发!
待办事项
- 删除内部API的进一步slevomat依赖。