phpcs(squizlabs/PHP_CodeSniffer)警告の一覧

phpcsとは

GitHub - squizlabs/PHP_CodeSniffer: PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards. - squizlabs/PHP_CodeSniffer

PHPコードのコーディングルールチェッカー的なツールです。PSR1、PSR2、PSR12、Zend、Pearのコーディングルールを内部にもっています。

次のファイル foo.php を

<?php
class Foo {
    function bar() {
        return $x+1;
    }
}
Code language: PHP (php)

phpcsにかけると、

$ ./vendor/bin/phpcs --standard=PSR12 foo.php 
 FILE: /xxx/yyy/foo.php
----------------------------------------------------------------------------------------------------
 FOUND 8 ERRORS AFFECTING 5 LINES
----------------------------------------------------------------------------------------------------
 1 | ERROR | [x] Header blocks must be separated by a single blank line
 2 | ERROR | [ ] Each class must be in a namespace of at least one level (a top-level vendor name)
 2 | ERROR | [x] Opening brace of a class must be on the line after the definition
 3 | ERROR | [ ] Visibility must be declared on method "bar"
 3 | ERROR | [x] Opening brace should be on a new line
 4 | ERROR | [x] Expected at least 1 space before "+"; 0 found
 4 | ERROR | [x] Expected at least 1 space after "+"; 0 found
 6 | ERROR | [x] Expected 1 newline at end of file; 0 found
----------------------------------------------------------------------------------------------------
 PHPCBF CAN FIX THE 6 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------------------------------------

 Time: 36ms; Memory: 6MBCode language: Bash (bash)

はじめてphpcsにかけると、警告が多くてびっくりするよ

ERRORを修正した結果

<?php

namespace Ninton;

class Foo
{
    public function bar()
    {
        return $x + 1;
    }
}
Code language: PHP (php)

インストール

composerでインストールします。

$ composer require --dev squizlabs/php_codesnifferCode language: Bash (bash)

使い方

コーディングルールとファイルを指定します。

$ ./vendor/bin/phpcs  --standard=PSR12  foo.phpCode language: Bash (bash)

ディレクトリを指定することもできます。

$ ./vendor/bin/phpcs  --standard=PSR12  ./web/Code language: Bash (bash)

jsやcssを除外するには、

$ ./vendor/bin/phpcs  --standard=PSR12  ./web/  --ignore="*.js|*.css"Code language: Bash (bash)

警告の [x] つきのものは、もう一つのコマンド phpcbf で自動修正できます。

$ ./vendor/bin/phpcbf  --standard=PSR12  foo.phpCode language: Bash (bash)

ルールのカスタマイズ

The Annotated Sample File

プロジェクトの全ファイルで、キャメルケース警告などを無視したい場合は、phpcs.xmlを作成します。

<?xml version="1.0"?>
<ruleset name="Local">
    <description>Local</description>
    <rule ref="PSR1">
        <exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"/>
        <exclude name="PSR1.Classes.ClassDeclaration"/>
        <exclude name="PSR1.Files.SideEffects"/>
    </rule>
    <rule ref="PSR2">
        <exclude name="Squiz.Classes.ValidClassName"/>
    </rule>
    <rule ref="PSR12">
    </rule>
</ruleset>Code language: HTML, XML (xml)

カレントディレクトリにphpcs.xmlを作っておくと、--standardオプションを省略できます。

$ ls phpcs.xml
phpcs.xml

$ ./vendor/bin/phpcs  foo.phpCode language: Bash (bash)

カレントディレクトリにphpcs.xmlがない場合は、--standardオプションでphpcs.xmlを指定します。

$ ./vendor/bin/phpcs  --standard=../phpcs.xml foo.phpCode language: Bash (bash)

ファイルごとの警告の抑制

例えば、1行が長すぎる警告(Generic.Files.LineLength)を

19 | WARNING | Line exceeds 120 characters; contains 130 charactersCode language: Bash (bash)

ファイル全体で抑制するには、先頭に、phpcs:disable を書いておきます。

<?php

// phpcs:disable Generic.Files.LineLengthCode language: PHP (php)

特定の行だけを抑制するには、直前に phpcs:ignoreを書くか、行末に phpcs:ignore を書きます。

<?php

// phpcs:ignore Generic.Files.LineLength
$x = "長い文字列xxxxxxxxxxxxxxxxxxxxxxxxxx";


$y = "長い文字列xxxxxxxxxxxxxxxxxxxxxxxxxx"; // phpcs:ignore Generic.Files.LineLengthCode language: PHP (php)

phpmdはクラス単位、メソッド単位の抑制ができますが、残念ながらphpcsはできません。

phpcsでは抑制したい範囲を、php:disable、php:enableで囲みます。

<?php

// phpcs:disable Generic.Files.LineLength
function foo()
{
    $x = "長い文字列xxxxxxxxxxxxxxxxxxxxxxxxxx";
    $y = "長い文字列xxxxxxxxxxxxxxxxxxxxxxxxxx";
}
// phpcs:enabled Generic.Files.LineLength

function bar()
{
    $x = "長い文字列xxxxxxxxxxxxxxxxxxxxxxxxxx";
    $y = "長い文字列xxxxxxxxxxxxxxxxxxxxxxxxxx";
}
Code language: PHP (php)

警告の一覧

Generic.Files.LineLength

Line exceeds 120 characters; contains 192 charactersCode language: plaintext (plaintext)

1行が長すぎます。

メソッドや関数の定義や呼び出しの引数並びが長い場合は、1行1引数に改行しします。

計算式に、メソッド呼び出しを含んでいて長い場合は、メソッドの結果を変数に代入してから、計算します。

ifの条件式が長い場合は、&& や || で改行したり、メソッドに分けます。

HTMLタグが長いは、タグを入れ子に改行します。それでも長い場合は、そのままにしておく、途中で改行する、1行1属性に改行するなど、好みでいいと思います。

AタグのURLクエリーが長い場合は、htmlエンコードとurlエンコードをする短い名前のヘルパー関数を用意したり、build_http_query関数を使ってヘルパー関数を用意します。

SQL文が長い場合は、文字列だけを返すメソッドに切り分けます。ユニットテストがないなら、SQL文はコピペしたままにしておきます。

巨大文字列の場合、別のphpファイルにして、requireします。このままでは表示されてしまうので、ob_start()とob_get_clean()を使って、変数にキャプチャします。

PSR1.Methods.CamelCapsMethodName

Method name "Foo::get_xx" is not in camel caps formatCode language: plaintext (plaintext)

メソッド名がキャメルケースではありません。

PSR1.Classes.ClassDeclaration

Each class must be in a file by itself and must be under a namespace (a top-level vendor name).Code language: plaintext (plaintext)

クラスにnamespaceを設定しましょう。

Each class must be in a file by itselfCode language: plaintext (plaintext)

1クラス、1ファイル。

PSR1.Files.SideEffects

A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 5 and the first side effect is on line 3.Code language: plaintext (plaintext)

「クラス、関数、定数の定義」と「副作用のある実行コード」を、一つのファイルに書いてはいけません。

レガシープロジェクトでは、この警告が大量にでます。

PSR2.Classes.MethodDeclaration

Method name "_hoge" must not be prefixed with an underscore to indicate visibilityCode language: plaintext (plaintext)

メソッド名の先頭にアンダースコアをつけても、(privateの)可視性を示すことはできません。

The abstract declaration must precede the visibility declarationCode language: plaintext (plaintext)

abstract は、public、protected、privateより前に。

The final declaration must precede the visibility declarationCode language: plaintext (plaintext)

final は、public、protected、privateより前に。

The static declaration must come after the visibility declarationCode language: plaintext (plaintext)

final は、public、protected、privateの後ろに。

PSR2.Classes.PropertyDeclaration

Property name "$_x" should not be prefixed with an underscore to indicate visibilityCode language: plaintext (plaintext)

プロパティ名の先頭にアンダースコアをつけても、(privateの)可視性を示すことはできません。

The var keyword must not be used to declare a propertyCode language: plaintext (plaintext)

プロパティは、varではなく、public、protected、privateを使いましょう。

There must not be more than one property declared per statementCode language: plaintext (plaintext)

カンマ区切りで、複数のプロパティを宣言しないように。1つの宣言で、1つのプロパティ。

The static declaration must come after the visibility declarationCode language: plaintext (plaintext)

static は、public、protected、privateの後ろに。

Visibility must be declared on property "$x"Code language: plaintext (plaintext)

static $x; ではなく、public static $x; としよう。

PSR12.Properties.ConstantVisibility

Visibility must be declared on all constants if your project supports PHP 7.1 or laterCode language: plaintext (plaintext)

PHP 7.1以降なら、クラス定数にpublic、protected、privateの指定をしましょう。

Squiz.Classes.ValidClassName

Class name "foo" is not in PascalCase formatCode language: plaintext (plaintext)

クラス名がパスカルケース(先頭大文字のキャメルケース)ではありません。

Squiz.Scope.MethodScope

Visibility must be declared on method "hoge"Code language: plaintext (plaintext)

メソッドに、public、protected、privateの指定をしましょう。

タイトルとURLをコピーしました