iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🌿

Creating Custom Rules to Get the Most Out of PHP_CodeSniffer

に公開
2

Introduction

I use PHP_CodeSniffer daily to check my code, and as a step toward mastering it, I tried creating some custom rules.

Environment

These are the versions that were on the MacBook I used for development.
*As of 2023/05/20

  • PHP 8.2.6
  • PHP_CodeSniffer 3.7.2

What I Created

I have uploaded them to GitHub.

https://github.com/naopusyu/phpcs-custom-rules

What Kind of Rules Did I Create?

PHPCSCustomRules.NamingConventions.SnakeCaseVariableName

A rule that variable names must be in snake_case.

// OK
$snake_case = 1;

// NG
$camelCase = 2;

I created this because there weren't many specific rules for variable naming conventions. In this implementation, any variable name that is not in snake_case will result in an error. However, I think it might cause false positives when extending code from packages that adopt camelCase, so I believe it needs improvement to allow for exclusions.

// Code in a package
class A 
{
    public string $propertyName = 'abc';
}

// Extending the package's code
class B extends A
{
    // This is extended but not snake_case, so it triggers an error.
    // Handling such cases is a future task.
    public string $propertyName = 'def';
}

PHPCSCustomRules.PHPUnit.DeprecatedTestAnnotation

A rule stating that the test prefix should be used for method names instead of the PHPUnit @test annotation.

// OK
public function testSelect()
{
}

// NG
/**
 * @test
 */
public function select()
{
}

I created this rule because I noticed while browsing PHPUnit issues that the @test annotation is planned to be deprecated in the future.
https://github.com/sebastianbergmann/phpunit/issues/4505

I have made it compatible with the phpcbf command so that it can be automatically converted to the correct format. However, it doesn't support Attributes yet, so I'd like to add that in the future.

Incidentally, I discovered that a similar rule already exists in Rector while I was creating this.
https://github.com/rectorphp/rector-phpunit/blob/main/docs/rector_rules_overview.md#replacetestannotationwithprefixedfunctionrector

Summary

I tried creating some rules for PHP_CodeSniffer.

While I was able to grasp the necessary file and directory structure by following the official tutorial, analyzing the contents of the array obtained by the getTokens method of PHP_CodeSniffer\Files\File was very tough. To be honest, I still don't understand it very well.
Since I might forget it if I don't use it for a while, I intend to deepen my understanding by regularly looking at existing rules.

Also, since I haven't created any test code this time, I would like to add some tests.

→ I've added them! ✨
https://zenn.dev/naopusyu/articles/2a9fe7f049d5dc

GitHubで編集を提案

Discussion

muno92muno92

https://github.com/squizlabs/PHP_CodeSniffer/blob/2dc7b5981488502fed92df99c1460530d741e666/src/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php#L180
逆の「変数名はキャメルケース以外はダメ」なルールはありましたが(ご存知でしたら失礼しました)、スネークケースで命名しているプロジェクトもあると思うので良さそうですね!

なおなお

ありがとうございます

そうなんですよね
キャメルケースはチェックできて、スネークケースはチェックできないってなったの今回作ってみようと思ったきっかけですね
(実際キャメルケースを採用しているプロジェクトが多いと思うので、スネークケースが異端なのかもしれないですが...)