此翻译可能已过时。

Mago 的 linter 共提供 175 条规则,分布在 9 个类别中。点击任意规则可展开其描述、要求、默认配置和示例。

特定集成的规则

部分规则只有在 Mago 检测到特定的库或框架时才会触发。每条规则都链接到上方章节中的完整描述。

CakePHP

Laravel

PHPUnit

Pest

Psl

Spiral

Symfony

Tempest

WordPress

Yii

清晰度

让意图更明确、减少阅读负担的规则。它们指出在技术上合法但会模糊代码意图的写法。

no-emptyerror

Detects the use of the empty() construct.

The empty() language construct can lead to ambiguous and potentially buggy code due to loose and counterintuitive definition of emptiness. It fails to clearly convey developer's intent or expectation, making it preferable to use explicit checks.


避免
<?php

if (!empty($myArray)) {
    // ...
}
推荐
<?php

if ($myArray === []) {
    // ...
}

选项类型默认值
enabledbooleantrue
levelstring"error"
explicit-octalwarning

Detects implicit octal numeral notation and suggests replacing it with explicit octal numeral notation.

此规则要求 PHP 8.1.0 或更高版本。

避免
<?php

$a = 0123;
推荐
<?php

$a = 0o123;

选项类型默认值
enabledbooleantrue
levelstring"warning"
instanceof-stringablewarning

Detects the legacy pattern is_object($x) && method_exists($x, '__toString') and suggests replacing it with $x instanceof Stringable for improved readability and performance.

Since PHP 8.0, all classes with __toString() automatically implement the Stringable interface.

此规则要求 PHP 8.0.0 或更高版本。

避免
<?php

function stringify(mixed $value): string {
    if (is_object($value) && method_exists($value, '__toString')) {
        return (string) $value;
    }

    return '';
}
推荐
<?php

function stringify(mixed $value): string {
    if ($value instanceof Stringable) {
        return (string) $value;
    }

    return '';
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
literal-named-argumentwarning

Enforces that literal values used as arguments in function or method calls are passed as named arguments.

This improves readability by clarifying the purpose of the literal value at the call site. It is particularly helpful for boolean flags, numeric constants, and null values where the intent is often ambiguous without the parameter name.

此规则要求 PHP 8.0.0 或更高版本。

避免
<?php

function set_option(string $key, bool $enable_feature) {}

set_option('feature_x', true); // ❌ intent unclear
推荐
<?php

function set_option(string $key, bool $enable_feature) {}

set_option(key: 'feature_x', enable_feature: true); // ✅ clear intent

选项类型默认值
check-first-argumentbooleanfalse
enabledbooleantrue
levelstring"warning"
thresholdnumber1
no-hash-emojiwarning

Discourages usage of the #️⃣ emoji in place of the ASCII #.

While PHP allows the use of emojis in comments, it is generally discouraged to use them in place of the normal ASCII # symbol. This is because it can confuse readers and may break external tools that expect the normal ASCII # symbol.


避免
<?php

#️⃣ This is a comment

#️⃣[MyAttribute] <- not a valid attribute
class Foo {}
推荐
<?php

# This is a comment

#[MyAttribute]
class Foo {}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-issetwarning

Detects the use of the isset() construct.

The isset() language construct checks whether a variable is set and is not null. However, it can lead to ambiguous code because it conflates two distinct checks: variable existence and null comparison. Using explicit null checks or the null coalescing operator (??) is often clearer and more maintainable.


避免
<?php

if (isset($value)) {
    // ...
}
推荐
<?php

if ($value !== null) {
    // ...
}

$result = $value ?? 'default';

选项类型默认值
allow-array-checksbooleanfalse
enabledbooleantrue
levelstring"warning"
no-multi-assignmentswarning

Flags any instances of multiple assignments in a single statement. This can lead to confusion and unexpected behavior, and is generally considered poor practice.


避免
<?php

$a = $b = 0;
推荐
<?php

$b = 0;
$a = $b;

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-nested-ternarywarning

Nested ternary expressions are disallowed to improve code clarity and prevent potential bugs arising from confusion over operator associativity.

In PHP 8.0 and later, the ternary operator (? :) is non-associative. Before PHP 8.0, it was left-associative, which is now deprecated. Most other programming languages treat it as right-associative. This inconsistency across versions and languages can make nested ternaries hard to reason about, even when using parentheses.


避免
<?php

$allowed = $user->isAdmin() ? true : ($user->isEditor() ? true : false);
推荐
<?php

if ($user->isAdmin()) {
    $allowed = true;
} else {
    $allowed = $user->isEditor();
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-shorthand-ternarywarning

Detects the use of the shorthand ternary and elvis operators.

Both shorthand ternary operator ($a ? : $b) and elvis operator ($a ?: $b) relies on loose comparison.


避免
<?php
$value = $foo ?: $default;
$value = $foo ? : $default;
推荐
<?php

$value = $foo ?? $default;
$value = $foo ? $foo : $default;

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-variable-variablewarning

Discourages usage of PHP's variable variables feature.

Variable variables can make code harder to read and maintain, as they introduce a level of indirection that can confuse readers and complicate static analysis.


避免
<?php

$foo = 'bar';
$varName = 'foo';

echo $$varName; // Outputs 'bar'
推荐
<?php

$foo = 'bar';

echo $foo; // Outputs 'bar'

选项类型默认值
enabledbooleantrue
levelstring"warning"
readable-literalwarning

Enforces using underscore separators in numeric literals for improved readability.

此规则要求 PHP 7.4.0 或更高版本。

避免
<?php

$a = 1000000;
$b = 0xCAFEF00D;
$c = 0b01011111;
推荐
<?php

$a = 1_000_000;
$b = 0xCAFE_F00D;
$c = 0b0101_1111;

选项类型默认值
enabledbooleantrue
levelstring"warning"
min-digitsnumber5
str-containswarning

Detects strpos($a, $b) !== false and strpos($a, $b) === false comparisons and suggests replacing them with str_contains($a, $b) or !str_contains($a, $b) for improved readability and intent clarity.

此规则要求 PHP 8.0.0 或更高版本。

避免
<?php

$a = 'hello world';
$b = 'world';

if (strpos($a, $b) !== false) {
    echo 'Found';
}
推荐
<?php

$a = 'hello world';
$b = 'world';

if (str_contains($a, $b)) {
    echo 'Found';
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
str-starts-withwarning

Detects strpos($a, $b) === 0 comparisons and suggests replacing them with str_starts_with($a, $b) for improved readability and intent clarity.

此规则要求 PHP 8.0.0 或更高版本。

避免
<?php

$a = 'hello world';
$b = 'hello';
if (strpos($a, $b) === 0) {
    echo 'Found';
}
推荐
<?php

$a = 'hello world';
$b = 'hello';
if (str_starts_with($a, $b)) {
    echo 'Found';
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
tagged-fixmewarning

Detects FIXME comments that are not tagged with a user or issue reference. Untagged FIXME comments are not actionable and can be easily missed by the team. Tagging the FIXME comment with a user or issue reference ensures that the issue is tracked and resolved.


避免
<?php

// FIXME: This is an invalid FIXME comment.
推荐
<?php

// FIXME(@azjezz) This is a valid FIXME comment.
// FIXME(azjezz) This is a valid FIXME comment.
// FIXME(#123) This is a valid FIXME comment.

选项类型默认值
enabledbooleantrue
levelstring"warning"
tagged-todowarning

Detects TODO comments that are not tagged with a user or issue reference. Untagged TODOs can be difficult to track and may be forgotten. Tagging TODOs with a user or issue reference makes it easier to track progress and ensures that tasks are not forgotten.


避免
<?php

// TODO: This is an invalid TODO comment.
推荐
<?php

// TODO(@azjezz) This is a valid TODO comment.
// TODO(azjezz) This is a valid TODO comment.
// TODO(#123) This is a valid TODO comment.

选项类型默认值
enabledbooleantrue
levelstring"warning"
use-dedicated-expectationwarning

Use dedicated matchers instead of function calls in Pest tests.

Instead of expect(is_array($x))->toBeTrue(), use expect($x)->toBeArray(). This provides clearer intent and better error messages.

Supported patterns:

  • Type checks: is_array, is_string, is_int, is_float, is_bool, is_numeric, is_callable, is_iterable, is_object, is_resource, is_scalar, is_null
  • String: str_starts_with, str_ends_with, ctype_alpha, ctype_alnum
  • Array: in_array, array_key_exists
  • File: is_file, is_dir, is_readable, is_writable, file_exists
  • Object: property_exists
此规则需要启用 Pest 集成。

避免
<?php

test('function calls', function () {
    expect(is_array($value))->toBeTrue();
    expect(is_string($value))->toBeTrue();
    expect(str_starts_with($string, 'prefix'))->toBeTrue();
    expect(in_array($item, $array))->toBeTrue();
    expect(is_file($path))->toBeTrue();
    expect(property_exists($obj, 'name'))->toBeTrue();
});
推荐
<?php

test('dedicated matchers', function () {
    expect($value)->toBeArray();
    expect($value)->toBeString();
    expect($string)->toStartWith('prefix');
    expect($array)->toContain($item);
    expect($path)->toBeFile();
    expect($obj)->toHaveProperty('name');
});

选项类型默认值
enabledbooleantrue
levelstring"warning"
use-simpler-expectationwarning

Simplify expect() expressions in Pest tests by using dedicated matchers.

This rule detects patterns where the expect() argument contains an expression that can be simplified:

  • expect(!$x)->toBeTrue() -> expect($x)->toBeFalse()
  • expect(!$x)->toBeFalse() -> expect($x)->toBeTrue()
  • expect($a > $b)->toBeTrue() -> expect($a)->toBeGreaterThan($b)
  • expect($a >= $b)->toBeTrue() -> expect($a)->toBeGreaterThanOrEqual($b)
  • expect($a < $b)->toBeTrue() -> expect($a)->toBeLessThan($b)
  • expect($a <= $b)->toBeTrue() -> expect($a)->toBeLessThanOrEqual($b)
  • expect($a === $b)->toBeTrue() -> expect($a)->toBe($b)
  • expect($a !== $b)->toBeTrue() -> expect($a)->not->toBe($b)
  • expect($x instanceof Y)->toBeTrue() -> expect($x)->toBeInstanceOf(Y::class)
  • expect($x >= min && $x <= max)->toBeTrue() -> expect($x)->toBeBetween(min, max)

Using dedicated matchers provides clearer intent and better error messages.

此规则需要启用 Pest 集成。

避免
<?php

test('complex expectations', function () {
    expect(!$condition)->toBeTrue();
    expect($a > $b)->toBeTrue();
    expect($a === $b)->toBeTrue();
    expect($obj instanceof ClassName)->toBeTrue();
    expect($x >= 1 && $x <= 10)->toBeTrue();
});
推荐
<?php

test('simplified expectations', function () {
    expect($condition)->toBeFalse();
    expect($a)->toBeGreaterThan($b);
    expect($a)->toBe($b);
    expect($obj)->toBeInstanceOf(ClassName::class);
    expect($x)->toBeBetween(1, 10);
});

选项类型默认值
enabledbooleantrue
levelstring"warning"
use-specific-expectationswarning

Use dedicated matchers instead of generic comparisons in Pest tests.

This rule suggests more specific matchers for common patterns:

  • toBe(true) / toEqual(true) -> toBeTrue()
  • toBe(false) / toEqual(false) -> toBeFalse()
  • toBe(null) / toEqual(null) -> toBeNull()
  • toBe([]) / toBe('') -> toBeEmpty()
  • not->toBeFalse() -> toBeTrue()
  • not->toBeTrue() -> toBeFalse()

Using dedicated matchers provides clearer intent and better error messages.

此规则需要启用 Pest 集成。

避免
<?php

test('generic comparisons', function () {
    expect($value)->toBe(true);
    expect($value)->toBe(false);
    expect($value)->toBe(null);
    expect($array)->toBe([]);
    expect($value)->not->toBeFalse();
});
推荐
<?php

test('specific matchers', function () {
    expect($value)->toBeTrue();
    expect($value)->toBeFalse();
    expect($value)->toBeNull();
    expect($array)->toBeEmpty();
});

选项类型默认值
enabledbooleantrue
levelstring"warning"
valid-docblocknote

Checks for syntax errors in docblock comments, such as malformed {@see} or {@link} annotations. It does not enforce the presence of docblocks or verify that declared types match the native declaration.


避免
<?php

/**
 * For more information, {@see https://example.com
 *
 * @param int $a
 *
 * @return int
 */
function foo($a) {
    return $a;
}
推荐
<?php

/**
 * For more information, {@see https://example.com}.
 *
 * @param int $a
 *
 * @return int
 */
function foo($a) {
    return $a;
}

选项类型默认值
enabledbooleantrue
levelstring"note"
missing-docshelp

Detects declarations that are missing a docblock.

This rule can be configured to require documentation for functions, classes, interfaces, traits, enums, enum cases, constants, statics, methods, and properties.

Documentation is useful when it explains intent, behaviour, usage, invariants, or other details that are not obvious from the code alone.


避免
<?php

function foo() {}
推荐
<?php

/**
 * A helpful piece of documentation.
 */
function foo() {}

选项类型默认值
classesbooleanfalse
constantsbooleantrue
enabledbooleanfalse
enum-casesbooleantrue
enumsbooleanfalse
functionsbooleantrue
interfacesbooleanfalse
levelstring"help"
methodsbooleantrue
propertiesbooleantrue
staticsbooleantrue
traitsbooleanfalse
no-negated-ternaryhelp

Flags ternary expressions whose condition is a logical negation (!$foo ? a : b).

A negated condition adds a layer of indirection the reader has to undo to follow the branches. Removing the negation and swapping the then and else branches produces an equivalent expression that reads more directly.


避免
<?php

$x = !$foo ? 1 : 0;
推荐
<?php

$x = $foo ? 0 : 1;

选项类型默认值
enabledbooleanfalse
levelstring"help"
no-short-bool-casthelp

Detects the use of double negation !!$expr as a shorthand for (bool) $expr.

The explicit (bool) cast is clearer about the intent to convert a value to a boolean.


避免
<?php

$active = !!$value;
推荐
<?php

$active = (bool) $value;

选项类型默认值
enabledbooleanfalse
levelstring"help"

最佳实践

PHP 的惯用写法和被广泛接受的约定。这些规则推动代码靠近经验丰富的 PHP 开发者所采用的现代风格。

final-controllererror

Enforces that controller classes are declared as final.

In modern MVC frameworks, controllers should be treated as entry points that orchestrate the application's response to a request. They are not designed to be extension points.

Extending controllers can lead to deep inheritance chains, making the codebase rigid and difficult to maintain. It's a best practice to favor composition (injecting services for shared logic) over inheritance.

If a controller is intended as a base for others, it should be explicitly marked as abstract. All other concrete controllers should be final to prevent extension.

此规则需要启用以下集成组合之一:Symfony;或 Laravel;或 Tempest;或 Spiral;或 CakePHP;或 Yii

避免
<?php

namespace App\Http\Controllers;

class UserController
{
    // ...
}
推荐
<?php

namespace App\Http\Controllers;

final class UserController
{
    // ...
}

选项类型默认值
enabledbooleantrue
levelstring"error"
no-inlineerror

Disallows inline content (text outside of PHP tags) in source files.

Most modern PHP applications are source-code only and do not use PHP as a templating language. Inline content before <?php, after ?>, or between PHP tags is typically unintentional and can cause issues such as unexpected output or "headers already sent" errors.

This rule is disabled by default and is intended for codebases that do not use PHP templates.


避免
Hello
<?php

echo "Hello, world!";

?>
Goodbye
推荐
<?php

namespace App;

echo "Hello, world!";

选项类型默认值
enabledbooleanfalse
levelstring"error"
psl-outputerror

This rule enforces the usage of Psl output functions over their PHP counterparts. Psl output functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

echo "Hello, world!";
推荐
<?php

Psl\IO\write_line("Hello, world!");

选项类型默认值
enabledbooleantrue
levelstring"error"
combine-consecutive-issetswarning

Suggests combining consecutive calls to isset() when they are joined by a logical AND.

For example, isset($a) && isset($b) can be turned into isset($a, $b), which is more concise and avoids repeated function calls. If one or both isset() calls are wrapped in parentheses, the rule will still warn, but it will not attempt an automated fix.


避免
<?php

if (isset($a) && isset($b)) {
    // ...
}
推荐
<?php

if (isset($a, $b)) {
    // ...
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
loop-does-not-iteratewarning

Detects loops (for, foreach, while, do-while) that unconditionally break or return before executing even a single iteration. Such loops are misleading or redundant since they give the impression of iteration but never actually do so.


避免
<?php

for ($i = 0; $i < 3; $i++) {
    break; // The loop never truly iterates, as this break is unconditional.
}
推荐
<?php

for ($i = 0; $i < 3; $i++) {
    echo $i;
    if ($some_condition) {
        break; // This break is conditional.
    }
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
middleware-in-routeswarning

This rule warns against applying middlewares in controllers.

Middlewares should be applied in the routes file, not in the controller.

此规则需要启用 Laravel 集成。

避免
<?php

namespace App\Http\Controllers;

class UserController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }
}
推荐
<?php

// routes/web.php
Route::get('/user', 'UserController@index')->middleware('auth');

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-array-accumulation-in-loopwarning

Detects O(n²) array accumulation patterns inside loops.

Calling array_merge(), array_merge_recursive(), array_unique(), or array_values() on an accumulator inside a loop copies the entire array on every iteration. Similarly, using spread syntax ([...$result, ...$item]) in a reassignment has the same cost.

Collect items first and transform once after the loop instead.


避免
<?php

$result = [];
foreach ($items as $item) {
    $result = array_merge($result, $item);
}
推荐
<?php

$chunks = [];
foreach ($items as $item) {
    $chunks[] = $item;
}
$result = array_merge(...$chunks);

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-direct-db-querywarning

This rule flags all direct method calls on the global $wpdb object. Direct database queries bypass the WordPress object cache, which can lead to poor performance. Using high-level functions like get_posts() is safer and more efficient.

此规则需要启用 WordPress 集成。

避免
<?php

global $wpdb;
$posts = $wpdb->get_results("SELECT * FROM {$wpdb->posts} WHERE post_author = 1");
推荐
<?php

$posts = get_posts(['author' => $author_id]);

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-ini-setwarning

Enforces that ini_set is not used.

Runtime configuration changes via ini_set make application behavior unpredictable and environment-dependent. They can mask misconfigured servers, introduce subtle bugs, and lead to inconsistent behavior between development, testing, and production environments.

Modern applications should rely on well-defined configuration through php.ini or framework specific configuration. This ensures that configuration is explicit, consistent, and controlled across all environments.

If a setting truly needs to vary between contexts, it should be handled at the infrastructure or framework configuration level, never by calling ini_set within the application code.


避免
<?php

// This can override server settings in an unpredictable way.
ini_set( 'display_errors', 1 );
ini_set( 'memory_limit', '256M' );
推荐
<?php

// In framework config files (e.g., wp-config.php), use constants.
define( 'WP_DEBUG', true );

// Use framework-provided functions where available.
wp_raise_memory_limit( 'admin' );

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-literal-namespace-stringwarning

Flags hardcoded fully qualified class name strings. Use ::class notation instead for better IDE support, refactoring safety, and static analysis.


避免
<?php

$className = 'App\Models\User';
推荐
<?php

$className = \App\Models\User::class;

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-parameter-shadowingwarning

Detects when a function or method parameter is shadowed by a loop variable or catch variable, making the original parameter value inaccessible.


避免
<?php

function read(array $domains, array $locales): void
{
    $translations = getTranslations($domains, $locales);

    foreach ($translations as $namespace => $locales) {
        // $locales now refers to the loop value, original argument is lost
    }
}
推荐
<?php

function read(array $domains, array $locales): void
{
    $translations = getTranslations($domains, $locales);

    foreach ($translations as $namespace => $namespaceLocales) {
        // $locales is still accessible
    }
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-side-effects-with-declarationswarning

Enforces that a PHP file either declares symbols (classes, functions, constants, interfaces, traits, enums) or causes side-effects, but not both.

Side-effects include echo, print, top-level function calls, assignments, include/require statements, and any other executable code outside of a symbol declaration.

This follows the PSR-1 basic coding standard: files SHOULD either declare symbols or execute logic, but SHOULD NOT do both.


避免
<?php

echo 'Loading utility file...';

class StringHelper
{
    public static function slugify(string $input): string
    {
        return '';
    }
}
推荐
<?php

namespace App;

class UserManager
{
    public function find(int $id): ?User
    {
        return null;
    }
}

选项类型默认值
allow-class-aliasbooleantrue
allow-class-existsbooleantrue
allow-conditional-declarationsbooleantrue
enabledbooleanfalse
levelstring"warning"
no-sprintf-concatwarning

Disallows string concatenation with the result of an sprintf call.

Concatenating with sprintf is less efficient and can be less readable than incorporating the string directly into the format template. This pattern creates an unnecessary intermediate string and can make the final output harder to see at a glance.


避免
<?php

$name = 'World';
$greeting = 'Hello, ' . sprintf('%s!', $name);
推荐
<?php

$name = 'World';
$greeting = sprintf('Hello, %s!', $name);

选项类型默认值
enabledbooleantrue
levelstring"warning"
prefer-anonymous-migrationwarning

Prefer using anonymous classes for Laravel migrations instead of named classes. Anonymous classes are more concise and reduce namespace pollution, making them the recommended approach for migrations.

此规则需要启用 Laravel 集成。

避免
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class MyMigration extends Migration {
    public function up(): void {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    public function down(): void {
        Schema::drop('flights');
    }
}

return new MyMigration();
推荐
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    public function up(): void {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    public function down(): void {
        Schema::drop('flights');
    }
};

选项类型默认值
enabledbooleantrue
levelstring"warning"
prefer-explode-over-preg-splitwarning

Detects calls to preg_split() whose pattern has no regex meta-characters and no modifiers, which means the split could be done with explode() and no regex engine at all.

explode() is faster (no compilation step), easier to read, and expresses the intent more directly when the separator is a plain string.

The rule only fires when:

  • the pattern argument is a string literal,
  • the pattern has no flags after the closing delimiter,
  • the content between the delimiters contains no regex meta-characters,
  • and the flags argument (if present) is literal 0.

避免
<?php

$parts = preg_split('/, /', $csv);
推荐
<?php

$parts = explode(', ', $csv);

选项类型默认值
enabledbooleanfalse
levelstring"warning"
prefer-first-class-callablewarning

Promotes the use of first-class callable syntax (...) for creating closures.

This rule identifies closures and arrow functions that do nothing but forward their arguments to another function or method. In such cases, the more concise and modern first-class callable syntax, introduced in PHP 8.1, can be used instead. This improves readability by reducing boilerplate code.

By default, this rule only checks method and static method calls. Optionally, function calls can also be checked by enabling check-functions, but this may produce false positives with internal PHP functions that enforce strict argument counts.

此规则要求 PHP 8.1.0 或更高版本。

避免
<?php

$names = ['Alice', 'Bob', 'Charlie'];
$uppercased_names = array_map(fn($name) => $formatter->format($name), $names);
推荐
<?php

$names = ['Alice', 'Bob', 'Charlie'];
$uppercased_names = array_map($formatter->format(...), $names);

选项类型默认值
check-functionsbooleanfalse
enabledbooleantrue
levelstring"warning"
prefer-test-attributewarning

Suggests using PHPUnit's #[Test] attribute instead of the test method name prefix.

When a method name starts with test, it can be replaced with a #[Test] attribute and a shorter method name. This is the modern PHPUnit style (PHPUnit 10+).

此规则需要启用 PHPUnit 集成。

避免
<?php

use PHPUnit\Framework\TestCase;

class UserTest extends TestCase
{
    public function testItReturnsFullName(): void {}
}
推荐
<?php

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\Test;

class UserTest extends TestCase
{
    #[Test]
    public function itReturnsFullName(): void {}
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
psl-array-functionswarning

This rule enforces the usage of Psl array functions over their PHP counterparts. Psl array functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

$filtered = array_filter($xs, fn($x) => $x > 2);
推荐
<?php

$filtered = Psl\Vec\filter($xs, fn($x) => $x > 2);

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-data-structureswarning

This rule enforces the usage of Psl data structures over their SPL counterparts.

Psl data structures are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

declare(strict_types=1);

$stack = new SplStack();
推荐
<?php

declare(strict_types=1);

use Psl\DataStructure\Stack;

$stack = new Stack();

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-datetimewarning

This rule enforces the usage of Psl DateTime classes and functions over their PHP counterparts.

Psl DateTime classes and functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

$dateTime = new DateTime();
推荐
<?php

$dateTime = new Psl\DateTime\DateTime();

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-math-functionswarning

This rule enforces the usage of Psl math functions over their PHP counterparts. Psl math functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

$abs = abs($number);
推荐
<?php

$abs = Psl\Math\abs($number);

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-randomness-functionswarning

This rule enforces the usage of Psl randomness functions over their PHP counterparts.

Psl randomness functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

$randomInt = random_int(0, 10);
推荐
<?php

$randomInt = Psl\SecureRandom\int(0, 10);

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-regex-functionswarning

This rule enforces the usage of Psl regex functions over their PHP counterparts.

Psl regex functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

$result = preg_match('/\w+/', 'Hello, World!');
推荐
<?php

$result = Psl\Regex\matches('Hello, World!', '/\w+/');

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-sleep-functionswarning

This rule enforces the usage of Psl sleep functions over their PHP counterparts.

Psl sleep functions are preferred because they are type-safe, provide more consistent behavior, and allow other tasks within the event loop to continue executing while the current Fiber pauses.

此规则需要启用 Psl 集成。

避免
<?php

sleep(1);
推荐
<?php

use Psl\Async;
use Psl\DateTime;

Async\sleep(DateTime\Duration::seconds(1));

选项类型默认值
enabledbooleantrue
levelstring"warning"
psl-string-functionswarning

This rule enforces the usage of Psl string functions over their PHP counterparts.

Psl string functions are preferred because they are type-safe and provide more consistent behavior.

此规则需要启用 Psl 集成。

避免
<?php

$capitalized = ucfirst($string);
推荐
<?php

$capitalized = Psl\Str\capitalize($string);

选项类型默认值
enabledbooleantrue
levelstring"warning"
require-namespacewarning

Detects files that contain definitions (classes, interfaces, enums, traits, functions, or constants) but do not declare a namespace. Using namespaces helps avoid naming conflicts and improves code organization.


避免
<?php

class Foo {}
推荐
<?php

namespace App;

class Foo {}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
single-class-per-filewarning

Ensures that each file contains at most one class-like definition (class, interface, enum, or trait).


避免
<?php

namespace App;

class Foo
{
}

class Bar
{
}
推荐
<?php

namespace App;

class Foo
{
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
use-wp-functionswarning

This rule encourages using WordPress's wrapper functions instead of native PHP functions for common tasks like HTTP requests, filesystem operations, and data handling. The WordPress APIs provide a consistent, secure, and reliable abstraction that works across different hosting environments.

此规则需要启用 WordPress 集成。

避免
<?php

// For remote requests:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://example.com/api/data');
// ...

// For filesystem operations:
file_put_contents('/path/to/my-file.txt', 'data');
推荐
<?php

// For remote requests:
$response = wp_remote_get('https://example.com/api/data');

// For filesystem operations:
global $wp_filesystem;
require_once ABSPATH . 'wp-admin/includes/file.php';
WP_Filesystem();
$wp_filesystem->put_contents( '/path/to/my-file.txt', 'data' );

选项类型默认值
enabledbooleantrue
levelstring"warning"
prefer-interfacenote

Detects when an implementation class is used instead of the interface.

此规则需要启用 Symfony 集成。

避免
<?php

use Symfony\Component\Serializer\Serializer;

class UserController
{
    public function __construct(Serializer $serializer)
    {
        $this->serializer = $serializer;
    }
}
推荐
<?php

use Symfony\Component\Serializer\SerializerInterface;

class UserController
{
    public function __construct(SerializerInterface $serializer)
    {
        $this->serializer = $serializer;
    }
}

选项类型默认值
enabledbooleantrue
levelstring"note"
prefer-while-loopnote

Suggests using a while loop instead of a for loop when the for loop does not have any initializations or increments. This can make the code more readable and concise.


避免
<?php

for (; $i < 10;) {
    echo $i;

    $i++;
}
推荐
<?php

while ($i < 10) {
    echo $i;

    $i++;
}

选项类型默认值
enabledbooleantrue
levelstring"note"
prefer-arrow-functionhelp

Promotes the use of arrow functions (fn() => ...) over traditional closures (function() { ... }).

This rule identifies closures that consist solely of a single return statement and suggests converting them to arrow functions.

此规则要求 PHP 7.4.0 或更高版本。

避免
<?php

$a = function($x) {
    return $x + 1;
};
推荐
<?php

$a = fn($x) => $x + 1;

选项类型默认值
enabledbooleantrue
levelstring"help"
prefer-early-continuehelp

Suggests using early continue pattern when a loop body contains only a single if statement.

This improves code readability by reducing nesting and making the control flow more explicit.


避免
<?php

for ($i = 0; $i < 10; $i++) {
    if ($condition) {
        doSomething();
    }
}
推荐
<?php

for ($i = 0; $i < 10; $i++) {
    if (!$condition) {
        continue;
    }
    doSomething();
}

选项类型默认值
enabledbooleantrue
levelstring"help"
max_allowed_statementsnumber0
prefer-pre-incrementhelp

Enforces the use of pre-increment (++$i) and pre-decrement (--$i) over post-increment ($i++) and post-decrement ($i--).

Pre-increment is marginally more efficient and is the convention used by the Symfony coding standards.

此规则需要启用 Symfony 集成。

避免
<?php

$i++;
$count--;
推荐
<?php

++$i;
--$count;

选项类型默认值
enabledbooleanfalse
levelstring"help"
prefer-self-return-typehelp

Suggests using self when a method's return type refers to its own enclosing class by name.

Using self decouples the signature from the class name, so renaming the class doesn't require updating return types. It also communicates intent more clearly: 'this returns an instance of the same class'.

Note: this rule does not apply to traits, because self inside a trait resolves to the using class, not the trait itself. If you want to return a subclass in inheritance-aware factory patterns, use static instead of self.


避免
<?php

final class Box
{
    public static function create(): Box
    {
        return new Box();
    }
}
推荐
<?php

final class Box
{
    public static function create(): self
    {
        return new self();
    }
}

选项类型默认值
enabledbooleanfalse
levelstring"help"
prefer-static-closurehelp

Suggests adding the static keyword to closures and arrow functions that don't use $this.

Static closures don't bind $this, making them more memory-efficient and their intent clearer.


避免
<?php

class Foo {
    public function bar() {
        // Missing static - doesn't use $this
        $fn = fn($x) => $x * 2;

        // Missing static - doesn't use $this
        $closure = function($x) {
            return $x * 2;
        };
    }
}
推荐
<?php

class Foo {
    public function bar() {
        // Static closure - doesn't use $this
        $fn = static fn($x) => $x * 2;

        // Non-static - uses $this
        $fn2 = fn() => $this->doSomething();

        // Static function - doesn't use $this
        $closure = static function($x) {
            return $x * 2;
        };
    }
}

选项类型默认值
enabledbooleantrue
levelstring"help"
prefer-view-arrayhelp

Prefer passing data to views using the array parameter in the view() function, rather than chaining the with() method.`

Using the array parameter directly is more concise and readable.

此规则需要启用 Laravel 集成。

避免
<?php

return view('user.profile')->with([
    'user' => $user,
    'profile' => $profile,
]);
推荐
<?php

return view('user.profile', [
    'user' => $user,
    'profile' => $profile,
]);

选项类型默认值
enabledbooleantrue
levelstring"help"
sorted-integer-keyshelp

Detects array literals with integer keys that are not in ascending order.

PHP internally uses a "packed array" optimization for arrays with integer keys in natural ascending order, which consumes significantly less memory and is faster. When integer keys are out of order, PHP falls back to a regular hash table.


避免
<?php

$weights = [
    3  => 0.506,
    5  => 0.21246,
    10 => 0.10823,
    20 => 0.06206,
    2  => 0.06011,
    4  => 0.01233,
];
推荐
<?php

$weights = [
    2  => 0.06011,
    3  => 0.506,
    4  => 0.01233,
    5  => 0.21246,
    10 => 0.10823,
    20 => 0.06206,
];

选项类型默认值
enabledbooleanfalse
levelstring"help"
use-compound-assignmenthelp

Enforces the use of compound assignment operators (e.g., +=, .=) over their more verbose equivalents ($var = $var + ...).

Using compound assignments is more concise and idiomatic. For string concatenation (.=), it can also be more performant as it avoids creating an intermediate copy of the string.


避免
<?php

$count = $count + 1;
$message = $message . ' Hello';
推荐
<?php

$count += 1;
$message .= ' Hello';

选项类型默认值
enabledbooleantrue
levelstring"help"
yoda-conditionshelp

This rule enforces the use of "Yoda" conditions for comparisons. The variable should always be on the right side of the comparison, while the constant, literal, or function call is on the left. This prevents the common bug of accidentally using an assignment (=) instead of a comparison (==), which would cause a fatal error in a Yoda condition instead of a silent logical bug.


避免
<?php

// Vulnerable to the accidental assignment bug, e.g., if ($is_active = true).
if ( $is_active === true ) { /* ... */ }
推荐
<?php

if ( true === $is_active ) { /* ... */ }
if ( 5 === $count ) { /* ... */ }

选项类型默认值
enabledbooleanfalse
levelstring"help"

一致性

保持整套代码风格一致。选定一种写法,这些规则帮助所有人坚持下去。

assertion-stylewarning

Enforces a consistent style for PHPUnit assertion calls within test methods.

Maintaining a consistent style (e.g., always using static:: or $this->) improves code readability and helps enforce team-wide coding standards in test suites. This rule can be configured to enforce the preferred style.

此规则需要启用 PHPUnit 集成。

避免
<?php
// configured style: "static"
final class SomeTest extends TestCase
{
    public function testSomething(): void
    {
        $this->assertTrue(true); // Incorrect style
        self::assertFalse(false); // Incorrect style
    }
}
推荐
<?php
// configured style: "static"
final class SomeTest extends TestCase
{
    public function testSomething(): void
    {
        static::assertTrue(true);
    }
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
stylestring"static"
file-namewarning

Ensures that a file containing a single class-like definition is named after that definition.

For example, a file containing class Foo must be named Foo.php. Optionally, this rule can also check functions: a file containing a single function foo must be named foo.php.


避免
<?php
// File: test.php

namespace App;

class Foo
{
}
推荐
<?php
// File: test.php

namespace App;

class test
{
}

选项类型默认值
check-functionsbooleanfalse
enabledbooleantrue
levelstring"warning"
no-alternative-syntaxwarning

Detects the use of alternative syntax for control structures (endif, endwhile, endfor, endforeach, endswitch).

The brace-style syntax is preferred for consistency with the rest of the codebase and is the convention used by the Symfony coding standards.


避免
<?php

if ($condition):
    echo 'yes';
endif;
推荐
<?php

if ($condition) {
    echo 'yes';
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-hash-commentwarning

Detects shell-style comments ('#') in PHP code. Double slash comments ('//') are preferred in PHP, as they are more consistent with the language's syntax and are easier to read.


避免
<?php

# This is a shell-style comment.
推荐
<?php

// This is a good comment.

选项类型默认值
enabledbooleantrue
levelstring"warning"
array-stylenote

Suggests using the short array style [..] instead of the long array style array(..), or vice versa, depending on the configuration. The short array style is more concise and is the preferred way to define arrays in PHP.


避免
<?php

// By default, 'short' is enforced, so array(...) triggers a warning:
$arr = array(1, 2, 3);
推荐
<?php

// By default, `style` is 'short', so this snippet is valid:
$arr = [1, 2, 3];

选项类型默认值
enabledbooleantrue
levelstring"note"
stylestring"short"
block-statementnote

Enforces that if, else, for, foreach, while, do-while statements always use a block statement body ({ ... }) even if they contain only a single statement.

This improves readability and prevents potential errors when adding new statements.


避免
<?php

if (true)
    echo "Hello";

for ($i = 0; $i < 10; $i++)
    echo $i;
推荐
<?php

if (true) {
    echo "Hello";
}

for ($i = 0; $i < 10; $i++) {
    echo $i;
}

选项类型默认值
enabledbooleantrue
levelstring"note"
braced-string-interpolationnote

Enforces the use of curly braces around variables within string interpolation.

Using curly braces ({$variable}) within interpolated strings ensures clarity and avoids potential ambiguity, especially when variables are followed by alphanumeric characters. This rule promotes consistent and predictable code.


避免
<?php

$a = "Hello, $name!";
$b = "Hello, ${name}!";
$c = "Hello, ${$name}!";
$d = "Hello, ${$object->getMethod()}!";
推荐
<?php

$a = "Hello, {$name}!";
$b = "Hello, {$name}!";
$c = "Hello, {$$name}!";
$d = "Hello, {${$object->getMethod()}}!";

选项类型默认值
enabledbooleantrue
levelstring"note"
no-alias-functionnote

Detects usage of function aliases (e.g., diskfreespace instead of disk_free_space) and suggests calling the canonical (original) function name instead. This is primarily for consistency and clarity.


避免
<?php

// 'diskfreespace' is an alias for 'disk_free_space'
$freeSpace = diskfreespace("/");
推荐
<?php

// 'disk_free_space' is the proper name instead of 'diskfreespace'
$freeSpace = disk_free_space("/");

选项类型默认值
enabledbooleantrue
levelstring"note"
no-php-tag-terminatornote

Discourages the use of ?><?php as a statement terminator. Recommends using a semicolon (;) instead for clarity and consistency.


避免
<?php

echo "Hello World" ?><?php
推荐
<?php

echo "Hello World";

选项类型默认值
enabledbooleantrue
levelstring"note"
no-trailing-spacenote

Detects trailing whitespace at the end of comments. Trailing whitespace can cause unnecessary diffs and formatting issues, so it is recommended to remove it.


避免
<?php

// This is a comment with trailing whitespace.
推荐
<?php

// This is a good comment.

选项类型默认值
enabledbooleantrue
levelstring"note"
string-stylenote

Enforces a consistent string style: either prefer string interpolation over concatenation, or prefer concatenation over interpolation.

With style: interpolation (default), flags concatenation like "foo" . $a . "bar" and suggests "foo{$a}bar" instead.

With style: concatenation, flags interpolation like "foo{$a}bar" and suggests "foo" . $a . "bar" instead.

Only simple, interpolable expressions are considered: variables, property accesses, array accesses, and method calls. Concatenation involving function calls, static access, or complex expressions is never flagged.


避免
<?php

// With the default `style: interpolation`:
$a = "Hello, " . $name . "!";
$b = "value: " . $obj->name;
推荐
<?php

// With the default `style: interpolation`:
$a = "Hello, {$name}!";
$b = "value: {$obj->name}";

// Complex expressions stay as concatenation (never flagged):
$c = "result: " . strtolower($input);
$d = "class: " . Foo::class;

选项类型默认值
enabledbooleanfalse
levelstring"note"
stylestring"interpolation"
ambiguous-constant-accesshelp

Enforces that all constant references made from within a namespace are explicit.

When an unqualified constant like PHP_VERSION is referenced from within a namespace, PHP performs a runtime fallback check (current namespace -> global namespace). This ambiguity can lead to unexpected behavior if a constant with the same name is later defined in the namespace.

Making references explicit improves readability and prevents bugs.


避免
<?php

namespace App;

// Ambiguous: could be App\PHP_VERSION or \PHP_VERSION
$version = PHP_VERSION;
推荐
<?php

namespace App;

use const PHP_VERSION;

// OK: Explicitly imported
$version1 = PHP_VERSION;

// OK: Explicitly global
$version2 = \PHP_VERSION;

选项类型默认值
enabledbooleanfalse
levelstring"help"
ambiguous-function-callhelp

Enforces that all function calls made from within a namespace are explicit.

When an unqualified function like strlen() is called from within a namespace, PHP performs a runtime fallback check (current namespace -> global namespace). This ambiguity prevents PHP from performing powerful compile-time optimizations, such as replacing a call to strlen() with the highly efficient STRLEN opcode.

Making calls explicit improves readability, prevents bugs, and allows for significant performance gains in some cases.


避免
<?php

namespace App;

// Ambiguous: could be App\strlen or \strlen
$length = strlen("hello");
推荐
<?php

namespace App;

use function strlen;

// OK: Explicitly imported
$length1 = strlen("hello");

// OK: Explicitly global
$length2 = \strlen("hello");

// OK: Explicitly namespaced
$value = namespace\my_function();

选项类型默认值
enabledbooleanfalse
levelstring"help"
class-namehelp

Detects class declarations that do not follow class naming convention.

Class names should be in class case, also known as PascalCase.


避免
<?php

class my_class {}

class myClass {}

class MY_CLASS {}
推荐
<?php

class MyClass {}

选项类型默认值
enabledbooleantrue
levelstring"help"
psrbooleanfalse
constant-namehelp

Detects constant declarations that do not follow constant naming convention.

Constant names should be in constant case, also known as UPPER_SNAKE_CASE.


避免
<?php

const myConstant = 42;
const my_constant = 42;
const My_Constant = 42;

class MyClass {
    public const int myConstant = 42;
    public const int my_constant = 42;
    public const int My_Constant = 42;
}
推荐
<?php

const MY_CONSTANT = 42;

class MyClass {
    public const int MY_CONSTANT = 42;
}

选项类型默认值
enabledbooleantrue
levelstring"help"
enum-namehelp

Detects enum declarations that do not follow class naming convention.

Enum names should be in class case, also known as PascalCase.


避免
<?php

enum my_enum {}
enum myEnum {}
enum MY_ENUM {}
推荐
<?php

enum MyEnum {}

选项类型默认值
enabledbooleantrue
levelstring"help"
function-namehelp

Detects function declarations that do not follow camel or snake naming convention.

Function names should be in camel case or snake case, depending on the configuration.


避免
<?php

function MyFunction() {}

function My_Function() {}
推荐
<?php

function my_function() {}

选项类型默认值
camelbooleanfalse
eitherbooleanfalse
enabledbooleantrue
levelstring"help"
interface-namehelp

Detects interface declarations that do not follow class naming convention.

Interface names should be in class case and suffixed with Interface, depending on the configuration.


避免
<?php

interface myInterface {}
interface my_interface {}
interface MY_INTERFACE {}
推荐
<?php

interface MyInterface {}

选项类型默认值
enabledbooleantrue
levelstring"help"
psrbooleanfalse
lowercase-keywordhelp

Enforces that PHP keywords (like if, else, return, function, etc.) be written in lowercase. Using uppercase or mixed case is discouraged for consistency and readability.

When the drupal integration is enabled, TRUE, FALSE, and NULL are exempted to match Drupal's coding standards (and the drupal formatter preset).


避免
<?PHP

IF (TRUE) {
    ECHO "Keywords not in lowercase";
} ELSE {
    RETURN;
}
推荐
<?php

if (true) {
    echo "All keywords in lowercase";
} else {
    return;
}

选项类型默认值
enabledbooleantrue
levelstring"help"
lowercase-type-hinthelp

Enforces that PHP type hints (like void, bool, int, float, etc.) be written in lowercase. Using uppercase or mixed case is discouraged for consistency and readability.


避免
<?php

function example(Int $param): VOID {
    return;
}
推荐
<?php

function example(int $param): void {
    return;
}

选项类型默认值
enabledbooleantrue
levelstring"help"
method-namehelp

Detects method declarations that do not follow the configured naming convention.

By default, method names should be in camelCase. Magic methods (prefixed with __) are always excluded.

The use-snake-case-for-tests option enforces snake_case for test methods (names starting with test), which is a common convention in PHPUnit.


避免
<?php

class Foo
{
    public function GetName(): string {}
    public function set_name(string $name): void {}
}
推荐
<?php

class Foo
{
    public function getName(): string {}
    public function setName(string $name): void {}
}

选项类型默认值
camelbooleantrue
eitherbooleanfalse
enabledbooleanfalse
levelstring"help"
use-snake-case-for-testsbooleanfalse
no-fully-qualified-global-class-likehelp

Disallows fully-qualified class-like references within a namespace.

Instead of using the backslash prefix (e.g., new \DateTime() or \Exception in a type hint), prefer an explicit use import statement. This improves readability and keeps imports centralized at the top of the file.


避免
<?php

namespace App;

$dt = new \DateTime();

function foo(\DateTime $dt): \Exception {}
推荐
<?php

namespace App;

use DateTime;
use Exception;

$dt = new DateTime();

function foo(DateTime $dt): Exception {}

选项类型默认值
enabledbooleanfalse
levelstring"help"
no-fully-qualified-global-constanthelp

Disallows fully-qualified references to global constants within a namespace.

Instead of using the backslash prefix (e.g., \PHP_VERSION), prefer an explicit use const import statement. This improves readability and keeps imports centralized at the top of the file.


避免
<?php

namespace App;

$version = \PHP_VERSION;
推荐
<?php

namespace App;

use const PHP_VERSION;

$version = PHP_VERSION;

选项类型默认值
enabledbooleanfalse
levelstring"help"
no-fully-qualified-global-functionhelp

Disallows fully-qualified references to global functions within a namespace.

Instead of using the backslash prefix (e.g., \strlen()), prefer an explicit use function import statement. This improves readability and keeps imports centralized at the top of the file.


避免
<?php

namespace App;

$length = \strlen("hello");
推荐
<?php

namespace App;

use function strlen;

$length = strlen("hello");

选项类型默认值
enabledbooleanfalse
levelstring"help"
property-namehelp

Detects class property declarations that do not follow camel or snake naming convention.

Property names should be in camel case or snake case, depending on the configuration.


避免
<?php

final class Foo {
    public string $My_Property;

    public function __construct(
        public int $My_Promoted_Property,
    ) {}
}
推荐
<?php

final class Foo {
    public string $myProperty;

    public function __construct(
        public int $myPromotedProperty,
    ) {}
}

选项类型默认值
camelbooleantrue
eitherbooleanfalse
enabledbooleanfalse
levelstring"help"
trait-namehelp

Detects trait declarations that do not follow class naming convention. Trait names should be in class case and suffixed with Trait, depending on the configuration.


避免
<?php

trait myTrait {}
trait my_trait {}
trait MY_TRAIT {}
推荐
<?php

trait MyTrait {}

选项类型默认值
enabledbooleantrue
levelstring"help"
psrbooleanfalse
variable-namehelp

Detects variable declarations that do not follow camel or snake naming convention.

Variable names should be in camel case or snake case, depending on the configuration.


避免
<?php

$MyVariable = 1;
$My_Variable = 2;

function foo($MyParam) {}
推荐
<?php

$my_variable = 1;

function foo($my_param) {}

选项类型默认值
camelbooleanfalse
check-parametersbooleantrue
eitherbooleantrue
enabledbooleanfalse
levelstring"help"

弃用

上游已弃用、未来会被移除的 PHP 特性与 API。请在它们彻底失效前迁移。

deprecated-casterror

Detect the usage of deprecated type casts in PHP code.

In PHP 8.5, the following type casts have been deprecated:

  • (integer): The integer cast has been deprecated in favor of (int).
  • (boolean): The boolean cast has been deprecated in favor of (bool).
  • (double): The double cast has been deprecated in favor of (float).
  • (binary): The binary cast has been deprecated in favor of (string).
此规则要求 PHP 8.5.0 或更高版本。

避免
<?php

(integer) $value;
推荐
<?php

(int) $value;

选项类型默认值
enabledbooleantrue
levelstring"error"
deprecated-shell-execute-stringerror

Detect the usage of deprecated shell execute strings in PHP code.

In PHP 8.5, the shell execute string syntax (enclosed in backticks, e.g., `ls -l`) has been deprecated.

This rule identifies instances of shell execute strings and provides guidance on how to replace them with safer alternatives, such as using the shell_exec() function or other appropriate methods for executing shell commands.

此规则要求 PHP 8.5.0 或更高版本。

避免
<?php

`ls -l`;
推荐
<?php

shell_exec('ls -l');

选项类型默认值
enabledbooleantrue
levelstring"error"
deprecated-switch-semicolonerror

Detect the usage of semicolon as a switch case separator.

In PHP 8.5, the use of a semicolon (;) as a case separator in switch statements has been deprecated.

Instead, the colon (:) should be used to separate case statements.

此规则要求 PHP 8.5.0 或更高版本。

避免
<?php

switch ($value) {
    case 1;
        // code for case 1
        break;
    case 2;
        // code for case 2
        break;
    default;
        // default case
        break;
}
推荐
<?php

switch ($value) {
    case 1:
        // code for case 1
        break;
    case 2:
        // code for case 2
        break;
    default:
        // default case
        break;
}

选项类型默认值
enabledbooleantrue
levelstring"error"
explicit-nullable-paramwarning

Detects parameters that are implicitly nullable and rely on a deprecated feature.

Such parameters are considered deprecated; an explicit nullable type hint is recommended.

此规则要求 PHP 8.4.0 或更高版本。

避免
<?php

function foo(string $param = null) {}

function bar(string $param = NULL) {}

function baz(object $param = null) {}
推荐
<?php

function foo(?string $param) {}

function bar(null|string $param) {}

function baz(null|object $param = null) {}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-underscore-classwarning

Detects class, interface, trait, or enum declarations named _.

Such names are considered deprecated; a more descriptive identifier is recommended.

此规则要求 PHP 8.4.0 或更高版本。

避免
<?php

class _ {}
推荐
<?php

class MyService {}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-void-reference-returnwarning

Detects functions, methods, closures, arrow functions, and set property hooks that return by reference from a void function. Such functions are considered deprecated; returning by reference from a void function is deprecated since PHP 8.0.

此规则要求 PHP 8.2.0 或更高版本。

避免
<?php

function &foo(): void {
    // ...
}
推荐
<?php

function &foo(): string {
    // ...
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
optional-param-orderwarning

Detects optional parameters defined before required parameters in function-like declarations. Such parameter order is considered deprecated; required parameters should precede optional parameters.

此规则要求 PHP 8.0.0 或更高版本。

避免
<?php

function foo(?string $optional = null, string $required): void {}
推荐
<?php

function foo(string $required, ?string $optional = null): void {}

选项类型默认值
enabledbooleantrue
levelstring"warning"

可维护性

难以长期维护的代码,过于复杂、纠缠或脆弱。这些规则提前暴露成本。

cyclomatic-complexityerror

Checks the cyclomatic complexity of classes, traits, enums, interfaces, functions, and closures.

Cyclomatic complexity is a measure of the number of linearly independent paths through a program's source code.


避免
<?php

function validateUser($user) {
    if (!isset($user['email'])) {
        return false;
    }

    if (!filter_var($user['email'], FILTER_VALIDATE_EMAIL)) {
        return false;
    }

    if (!isset($user['age'])) {
        return false;
    }

    if ($user['age'] < 18) {
        return false;
    }

    if ($user['age'] > 120) {
        return false;
    }

    if (!isset($user['name'])) {
        return false;
    }

    if (strlen($user['name']) < 2) {
        return false;
    }

    if (!isset($user['country'])) {
        return false;
    }

    if (!in_array($user['country'], ['US', 'UK', 'CA'])) {
        return false;
    }

    if (isset($user['phone'])) {
        if (!preg_match('/^\d{10}$/', $user['phone'])) {
            return false;
        }
    }

    if (isset($user['preferences'])) {
        if (is_array($user['preferences'])) {
            foreach ($user['preferences'] as $key => $value) {
                if ($key === 'newsletter') {
                    if ($value !== true && $value !== false) {
                        return false;
                    }
                }
            }
        }
    }

    if (isset($user['address'])) {
        if (!isset($user['address']['street'])) {
            return false;
        }
        if (!isset($user['address']['city'])) {
            return false;
        }
    }

    return true;
}
推荐
<?php

function validateUser($user) {
    if (!isValidEmail($user['email'])) {
        return false;
    }

    if (!isValidAge($user['age'])) {
        return false;
    }

    if (!hasRequiredFields($user)) {
        return false;
    }

    return true;
}

function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

function isValidAge($age) {
    return $age >= 18 && $age <= 120;
}

function hasRequiredFields($user) {
    return isset($user['name']) && isset($user['email']);
}

选项类型默认值
enabledbooleantrue
levelstring"error"
method-thresholdnullnull
thresholdnumber15
excessive-parameter-listerror

Detects functions, closures, and methods with too many parameters.

If the number of parameters exceeds a configurable threshold, an issue is reported.


避免
<?php

function createUser($name, $email, $password, $age, $country, $city, $zipCode) {
    return true;
}
推荐
<?php

function processOrder($orderId, $userId, $total, $status, $date) {
    return true;
}

选项类型默认值
constructor-thresholdnullnull
enabledbooleantrue
levelstring"error"
thresholdnumber5
kan-defecterror

Detects classes, traits, interfaces, functions, and closures with high kan defect.

The "Kan Defect" metric is a heuristic for estimating defect proneness in a class or similar structure. It counts control-flow statements (while, do, foreach, if, and switch) and sums them using a formula loosely based on the work of Stephen H. Kan.

References:

  • https://github.com/phpmetrics/PhpMetrics/blob/c43217cd7783bbd54d0b8c1dd43f697bc36ef79d/src/Hal/Metric/Class_/Complexity/KanDefectVisitor.php
  • https://phpmetrics.org/

避免
<?php

function handleRequest($request) {
    if (empty($request)) {
        return null;
    }

    if (!isset($request['type'])) {
        return null;
    }

    switch ($request['type']) {
        case 'create':
            if (!isset($request['data'])) {
                return null;
            }
            break;
        case 'update':
            if (!isset($request['id'])) {
                return null;
            }
            break;
        case 'delete':
            if (!isset($request['id'])) {
                return null;
            }
            break;
    }

    if (isset($request['filters'])) {
        foreach ($request['filters'] as $key => $value) {
            switch ($key) {
                case 'status':
                    if ($value === 'active') {
                        // filter
                    }
                    break;
                case 'category':
                    if (!empty($value)) {
                        // filter
                    }
                    break;
            }
        }
    }

    while (!empty($request['items'])) {
        $item = array_shift($request['items']);
        if ($item['valid']) {
            foreach ($item['tags'] as $tag) {
                if ($tag === 'important') {
                    // process
                }
            }
        }
    }

    foreach ($request['metadata'] as $meta) {
        switch ($meta['type']) {
            case 'timestamp':
                break;
            case 'user':
                break;
        }
    }

    return ['status' => 'success'];
}
推荐
<?php

function handleRequest($request) {
    $validated = validateRequest($request);
    $processed = processRequest($validated);
    return formatResponse($processed);
}

function validateRequest($request) {
    if (empty($request['type'])) {
        return null;
    }
    return $request;
}

function processRequest($request) {
    return match($request['type']) {
        'create' => createResource($request),
        'update' => updateResource($request),
        'delete' => deleteResource($request),
        default => null
    };
}

function formatResponse($data) {
    return ['status' => 'success', 'data' => $data];
}

选项类型默认值
enabledbooleantrue
levelstring"error"
thresholdnumber1.6
too-many-enum-caseserror

Detects enums with too many cases.

This rule checks the number of cases in enums. If the number of cases exceeds a configurable threshold, an issue is reported.


避免
<?php

enum LargeEnum {
    case A;
    case B;
    case C;
    case D;
    case E;
    case F;
    case G;
    case H;
    case I;
    case J;
    case K;
    case L;
    case M;
    case N;
    case O;
    case P;
    case Q;
    case R;
    case S;
    case T;
    case U;
}
推荐
<?php

enum SimpleEnum {
    case A;
    case B;
    case C;
}

选项类型默认值
enabledbooleantrue
levelstring"error"
thresholdnumber20
too-many-methodserror

Detects class-like structures with too many methods.

This rule checks the number of methods in classes, traits, enums, and interfaces. If the number of methods exceeds a configurable threshold, an issue is reported.


避免
<?php

class ComplexClass {
    public function a() {}
    public function b() {}
    public function c() {}
    public function d() {}
    public function e() {}
    public function f() {}
    public function g() {}
    public function h() {}
    public function i() {}
    public function j() {}
    public function k() {}
    public function l() {}
    public function m() {}
    public function n() {}
    public function o() {}
    public function p() {}
    public function q() {}
    public function r() {}
    public function s() {}
    public function t() {}
    public function u() {}
}
推荐
<?php

class SimpleClass {
    public function a() {}
    public function b() {}
}

选项类型默认值
count-hooksbooleanfalse
count-setters-and-gettersbooleanfalse
enabledbooleantrue
levelstring"error"
thresholdnumber10
too-many-propertieserror

Detects class-like structures with too many properties.

This rule checks the number of properties in classes, traits, and interfaces. If the number of properties exceeds a configurable threshold, an issue is reported.


避免
<?php

class ComplexClass {
    public $a; public $b; public $c; public $d; public $e;
    public $f; public $g; public $h; public $i; public $j; public $k;
}
推荐
<?php

class SimpleClass {
    public $a;
    public $b;
}

选项类型默认值
enabledbooleantrue
levelstring"error"
thresholdnumber10
excessive-nestingwarning

Checks if the nesting level in any block exceeds a configurable threshold.

Deeply nested code is harder to read, understand, and maintain. Consider refactoring to use early returns, helper methods, or clearer control flow.

The function-like-threshold option allows setting a separate, typically lower, threshold for individual functions, methods, closures, and property hooks.


避免
<?php

if ($a) {
    if ($b) {
        if ($c) {
            if ($d) {
                if ($e) {
                    if ($f) {
                        if ($g) {
                            if ($h) {
                                echo "Too deeply nested!";
                            }
                        }
                    }
                }
            }
        }
    }
}
推荐
<?php

if ($condition) {
    while ($otherCondition) {
        echo "Hello"; // nesting depth = 2
    }
}

选项类型默认值
enabledbooleantrue
function-like-thresholdnullnull
levelstring"warning"
thresholdnumber7
halsteadwarning

Computes Halstead metrics (volume, difficulty, effort) and reports if they exceed configured thresholds.

Halstead metrics are calculated by counting operators and operands in the analyzed code. For more info: https://en.wikipedia.org/wiki/Halstead_complexity_measures


避免
<?php

function processOrderData($orders) {
    $result = [];
    $total1 = 0;
    $total2 = 0;
    $total3 = 0;
    $discount1 = 0;
    $discount2 = 0;
    $discount3 = 0;
    $count1 = 0;
    $count2 = 0;
    $count3 = 0;
    $sum1 = 0;
    $sum2 = 0;
    $sum3 = 0;

    for ($i = 0; $i < count($orders); $i++) {
        $order = $orders[$i];
        if ($order['status'] === 'pending') {
            $price = $order['price'];
            $quantity = $order['quantity'];
            $subtotal = $price * $quantity;
            $total1 = $total1 + $subtotal;

            if ($subtotal > 100) {
                $discount1 = $subtotal * 0.1;
                $total1 = $total1 - $discount1;
                $count1 = $count1 + 1;
            }

            if ($subtotal > 200) {
                $discount2 = $subtotal * 0.15;
                $total2 = $total2 + $subtotal - $discount2;
                $count2 = $count2 + 1;
            }

            if ($subtotal > 300) {
                $discount3 = $subtotal * 0.2;
                $total3 = $total3 + $subtotal - $discount3;
                $count3 = $count3 + 1;
            }

            $sum1 = $sum1 + $price;
            $sum2 = $sum2 + $quantity;
            $sum3 = $sum3 + $subtotal;

            for ($j = 0; $j < $quantity; $j++) {
                $itemCost = $price / $quantity;
                $taxRate = 0.08;
                $tax = $itemCost * $taxRate;
                $finalCost = $itemCost + $tax;
                $sum1 = $sum1 + $finalCost;

                if ($finalCost > 50) {
                    $extraDiscount = $finalCost * 0.05;
                    $sum2 = $sum2 + $extraDiscount;
                }
            }
        }
    }

    $result['total1'] = $total1;
    $result['total2'] = $total2;
    $result['total3'] = $total3;
    $result['count1'] = $count1;
    $result['count2'] = $count2;
    $result['count3'] = $count3;
    $result['sum1'] = $sum1;
    $result['sum2'] = $sum2;
    $result['sum3'] = $sum3;

    return $result;
}
推荐
<?php

function processOrderData($orders) {
    $filtered = filterValidOrders($orders);
    $totals = calculateTotals($filtered);
    return applyDiscounts($totals);
}

function filterValidOrders($orders) {
    return array_filter($orders, fn($order) => $order['status'] === 'valid');
}

function calculateTotals($orders) {
    return array_map(fn($order) => $order['price'] * $order['quantity'], $orders);
}

function applyDiscounts($totals) {
    return array_map(fn($total) => $total > 100 ? $total * 0.9 : $total, $totals);
}

选项类型默认值
difficulty-thresholdnumber12.0
effort-thresholdnumber5000.0
enabledbooleantrue
levelstring"warning"
volume-thresholdnumber1000.0
no-gotonote

Detects the use of goto statements and labels. The goto statement can make code harder to read, understand, and maintain. It can lead to "spaghetti code" and make it difficult to follow the flow of execution.


避免
<?php

$i = 0;
loop:
if ($i >= 10) {
    goto end;
}

$i++;
goto loop;
end:
推荐
<?php

$i = 0;
while ($i < 10) {
    if ($i === 5) {
        break; // Structured control flow.
    }
    $i++;
}

选项类型默认值
enabledbooleantrue
levelstring"note"
no-boolean-flag-parameterhelp

Flags function-like parameters that use a boolean type.

Boolean flag parameters can indicate a violation of the Single Responsibility Principle (SRP). Refactor by extracting the flag logic into its own class or method.


避免
<?php

function get_difference(string $a, string $b, bool $ignore_case): string {
    // ...
}
推荐
<?php

function get_difference(string $a, string $b): string {
    // ...
}

function get_difference_case_insensitive(string $a, string $b): string {
    // ...
}

选项类型默认值
enabledbooleantrue
exclude-constructorsbooleantrue
exclude-settersbooleanfalse
levelstring"help"
no-else-clausehelp

Flags if statements that include an else or elseif branch.

Using else or elseif can lead to deeply nested code and complex control flow. This can often be simplified by using early returns (guard clauses), which makes the code easier to read and maintain by reducing its cyclomatic complexity.


避免
<?php

function process($user) {
    if ($user->isVerified()) {
        // "Happy path" is nested
        $user->login();
    } else {
        // Logic is split across branches
        return;
    }
}
推荐
<?php

function process($user) {
    if (!$user->isVerified()) {
        return; // Early return
    }

    // "Happy path" continues here
    $user->login();
}

选项类型默认值
enabledbooleantrue
levelstring"help"

冗余

无用代码、无效值,以及没有可观察效果的写法。清理它们让代码更诚实。

inline-variable-returnwarning

Detects unnecessary variable assignments immediately before returning the variable.

When a variable is only used once right after being assigned, the assignment can be inlined into the return statement.


避免
<?php

function getValue() {
    $result = computeResult();
    return $result;
}

function getArray() {
    $arr = [1, 2, 3];
    return $arr;
}
推荐
<?php

function getValue() {
    return computeResult();
}

function process() {
    $result = computeResult();
    log($result);
    return $result;
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-iterator-to-array-in-foreachwarning

Detects iterator_to_array() calls used directly as a foreach expression.

Since foreach natively supports any Traversable, wrapping an iterator in iterator_to_array() is redundant and causes unnecessary memory allocation.


避免
<?php

foreach (iterator_to_array($iterator) as $value) {
    // ...
}
推荐
<?php

foreach ($iterator as $value) {
    // ...
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-redundant-literal-returnwarning

Detects redundant literal guard patterns where an if statement checks if a variable equals a literal and returns that same literal, followed by returning the variable.

This pattern is redundant because if the variable equals the literal, returning the variable would return the same value anyway.

This includes patterns with else clauses and elseif chains where all branches follow the same redundant pattern.


避免
<?php

function getValue($x) {
    if ($x === null) {
        return null;
    }
    return $x;
}

function getWithElse($x) {
    if ($x === null) {
        return null;
    } else {
        return $x;
    }
}

function getWithElseIf($x) {
    if ($x === null) {
        return null;
    } elseif ($x === '') {
        return '';
    }
    return $x;
}
推荐
<?php

function getValue($x) {
    return $x;
}

function getValueOrDefault($x, $default) {
    if ($x === null) {
        return $default;
    }
    return $x;
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-redundant-usewarning

Detects use statements that import items that are never used or are redundant because they import from the same namespace.


避免
<?php
namespace App;

use App\Helpers\ArrayHelper;
use App\Helpers\StringHelper; // StringHelper is not used.

$result = ArrayHelper::combine([]);
推荐
<?php
namespace App;

use App\Helpers\ArrayHelper;

$result = ArrayHelper::combine([]);

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-self-assignmentwarning

Detects and removes self-assignments where a variable or property is assigned to itself.

Self-assignments have no effect and are typically mistakes or leftover from refactoring. For object properties, the fix is marked as potentially unsafe because reading or writing properties may have side effects through magic methods (__get, __set) or property hooks (PHP 8.4+).


避免
<?php

$a = $a;
$this->x = $this->x;
$foo->bar = $foo->bar;
推荐
<?php

$a = $b;
$this->x = $other->x;
$foo->bar = $baz->bar;

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-empty-commentnote

Detects empty comments in the codebase. Empty comments are not useful and should be removed to keep the codebase clean and maintainable.


避免
<?php

//
#
/**/
推荐
<?php

// This is a useful comment.
//
// And so is this whole single line comment block, including the enclosed empty line.
# This is also a useful comment.
/**
 * This is a docblock.
 */

选项类型默认值
enabledbooleantrue
levelstring"note"
preserve-single-line-commentsbooleanfalse
no-empty-loopnote

Detects loops (for, foreach, while, do-while) that have an empty body. An empty loop body does not perform any actions and is likely a mistake or redundant code.


避免
<?php

while (should_wait()) {
    // Empty loop body
}
推荐
<?php

foreach ($items as $item) {
    process($item);
}

选项类型默认值
enabledbooleantrue
levelstring"note"
no-is-nullnote

Detects usage of the is_null() function and suggests using a strict === null comparison instead.

The is_null() function is redundant because === null achieves the same result with clearer intent and without the overhead of a function call.


避免
<?php

if (is_null($value)) {
    // ...
}
推荐
<?php

if ($value === null) {
    // ...
}

选项类型默认值
enabledbooleanfalse
levelstring"note"
constant-conditionhelp

Detects if statements where the condition is a constant that always evaluates to true or false.

Such statements are redundant. If the condition is always true, the if wrapper is unnecessary. If it's always false, the enclosed code is dead and can be removed or refactored.


避免
<?php
if (true) {
    echo "This will always run";
}

if (false) {
    echo "This is dead code";
}
推荐
<?php
if ($variable > 10) {
    echo "Greater than 10";
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-closing-taghelp

Detects redundant closing tags ( ?> ) at the end of a file.


避免
<?php

echo "Hello, world!";

?>
推荐
<?php

echo "Hello, world!";

选项类型默认值
enabledbooleantrue
levelstring"help"
no-noophelp

Detects redundant noop statements.


避免
<?php

;
推荐
<?php

echo "Hello, world!";

选项类型默认值
enabledbooleantrue
levelstring"help"
no-null-property-inithelp

Detects redundant = null initialization on untyped properties.

Untyped properties already default to null, making an explicit = null initializer unnecessary.


避免
<?php

class Foo {
    public $name = null;
}
推荐
<?php

class Foo {
    public $name;
}

选项类型默认值
enabledbooleanfalse
levelstring"help"
no-protected-in-finalhelp

Detects protected items in final classes or enums.


避免
<?php

final class Foo {
    protected string $foo;
    protected(set) string $bar;
    protected private(set) string $baz;

    protected function fun(): void {
        // ...
    }
}
推荐
<?php

final class Foo {
    private string $foo;
    private(set) string $bar;
    private string $baz;

    private function fun(): void {
        // ...
    }
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-binary-string-prefixhelp

Detects the redundant b/B prefix on string literals. The binary string prefix has no effect in PHP and can be safely removed.


避免
<?php

$foo = b'hello';
$bar = b"world";
推荐
<?php

$foo = 'hello';
$bar = "world";

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-blockhelp

Detects redundant blocks around statements.


避免
<?php

{
    echo "Hello, world!";
}
推荐
<?php

echo "Hello, world!";

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-continuehelp

Detects redundant continue statements in loops.


避免
<?php

while (true) {
    echo "Hello, world!";
    continue; // Redundant `continue` statement
}
推荐
<?php

while (true) {
    echo "Hello, world!";
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-elsehelp

Flags if/else statements where the if branch always terminates control flow (via return, throw, exit, die, continue, or break).

When the if branch unconditionally terminates, the else branch becomes unnecessary nesting. Extracting the else body to follow the if flattens the control flow without changing semantics.


避免
<?php

function process($user) {
    if (!$user->isVerified()) {
        return;
    } else {
        $user->login();
    }
}
推荐
<?php

function process($user) {
    if (!$user->isVerified()) {
        return;
    }

    $user->login();
}

选项类型默认值
enabledbooleanfalse
levelstring"help"
no-redundant-filehelp

Detects redundant files that contain no executable code or declarations.


避免
<?php

declare(strict_types=1);
// This file is redundant.
推荐
<?php

declare(strict_types=1);

function foo(): void {
    return 42;
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-finalhelp

Detects redundant final modifiers on methods in final classes or enum methods.


避免
<?php

final class Foo {
    final public function bar(): void {
        // ...
    }
}
推荐
<?php

final class Foo {
    public function bar(): void {
        // ...
    }
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-issethelp

Detects redundant arguments in isset() calls where a nested access already implies the parent checks.

For example, isset($d, $d['first'], $d['first']['second']) can be simplified to isset($d['first']['second']) because checking a nested array access or property access implicitly verifies that all parent levels exist.


避免
<?php

if (isset($d, $d['first'], $d['first']['second'])) {
    echo 'all present';
}
推荐
<?php

if (isset($d['first']['second'])) {
    echo 'all present';
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-labelhelp

Detects redundant goto labels that are declared but not used.


避免
<?php

label:
echo "Hello, world!";
推荐
<?php

goto end;
echo "Hello, world!";
end:

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-mathhelp

Detects redundant mathematical operations that can be simplified or removed. Includes operations like multiplying by 1/-1, adding 0, modulo 1/-1, etc.


避免
<?php

$result = $value * 1;
$sum = 0 + $total;
$difference = $value - 0;
$remainder = $x % 1;
$negative = $value * -1;
推荐
<?php

$result = $value * 2;
$sum = 1 + $total;
$difference = $value - 1;
$remainder = $x % 2;

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-method-overridehelp

Detects methods that override a parent method but only call the parent method with the same arguments.


避免
<?php

class Parent
{
    public function foo(): void
    {
        // ...
    }
}

class Child extends Parent
{
    public function foo(): void
    {
        parent::foo();
    }
}
推荐
<?php

class Parent
{
    public function foo(): void
    {
        // ...
    }
}

class Child extends Parent
{
    public function foo(): void
    {
        parent::foo();

        echo 'Additional logic here';
    }
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-nullsafehelp

Flags the use of the nullsafe operator (?->) in contexts where its null-checking behavior is redundant.

This occurs in two common situations:

  1. When an expression using ?-> is immediately followed by the null coalescing operator (??).
  2. When an expression using ?-> is checked with isset().

In both scenarios, the surrounding language construct (?? or isset()) already handles null values safely, making the ?-> operator superfluous and the code unnecessarily verbose.


避免
<?php

$name = $user?->name ?? 'Guest';

if (isset($user?->profile)) {
    // Do something with $user->profile
}
推荐
<?php

$name = $user->name ?? 'Guest';

if (isset($user->profile)) {
    // Do something with $user->profile
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-parentheseshelp

Detects redundant parentheses around expressions.


避免
<?php

$foo = (42);
推荐
<?php

$foo = 42;

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-readonlyhelp

Detects redundant readonly modifiers on properties.


避免
<?php

readonly class User
{
    public readonly $name;
}
推荐
<?php

readonly class User
{
    public $name;
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-string-concathelp

Detects redundant string concatenation expressions.


避免
<?php

$foo = "Hello" . " World";
推荐
<?php

$foo = "Hello World";

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-write-visibilityhelp

Detects redundant write visibility modifiers on properties.


避免
<?php

final class User
{
    public public(set) $name;
}
推荐
<?php

final class User
{
    public $name;
}

选项类型默认值
enabledbooleantrue
levelstring"help"
no-redundant-yield-fromhelp

Detects redundant use of yield from with single-element array literals.

Using yield from with a single-element array literal creates unnecessary overhead in the generated opcodes. Direct yield is simpler and more efficient.


避免
<?php

function gen(): Generator {
    yield from [1];
    yield from ['foo' => new stdClass()];
}
推荐
<?php

function gen(): Generator {
    yield 1;
    yield 'foo' => new stdClass();
}

选项类型默认值
enabledbooleantrue
levelstring"help"

安全

标记安全漏洞的规则,如注入向量、不安全的反序列化,以及不可信输入流入敏感位置。

no-db-schema-changeerror

This rule flags any attempt to alter the database schema (using CREATE, ALTER, or DROP) within a $wpdb call. Schema modifications must only occur within a plugin activation hook to prevent catastrophic performance issues and data corruption.

此规则需要启用 WordPress 集成。

避免
<?php

// This schema change runs on every page load, which is very dangerous.
global $wpdb;
$wpdb->query("ALTER TABLE {$wpdb->posts} ADD my_column VARCHAR(255)");
推荐
<?php

function my_plugin_activate() {
    global $wpdb;

    // Running schema changes inside an activation hook is safe.
    $wpdb->query("ALTER TABLE {$wpdb->posts} ADD my_column VARCHAR(255)");
}

register_activation_hook(__FILE__, 'my_plugin_activate');

选项类型默认值
enabledbooleantrue
levelstring"error"
no-insecure-comparisonerror

Detects insecure comparison of passwords or tokens using ==, !=, ===, or !==.

These operators are vulnerable to timing attacks, which can expose sensitive information. Instead, use hash_equals for comparing strings or password_verify for validating hashes.


避免
<?php

if ($storedToken == $userToken) {
    // Vulnerable to timing attacks
}
推荐
<?php

if (hash_equals($storedToken, $userToken)) {
    // Valid token
}

选项类型默认值
enabledbooleantrue
levelstring"error"
no-literal-passworderror

Detects the use of literal values for passwords or sensitive data. Storing passwords or sensitive information as literals in code is a security risk and should be avoided. Use environment variables or secure configuration management instead.


避免
<?php

$password = "supersecret";
推荐
<?php

$password = getenv('DB_PASSWORD');

选项类型默认值
enabledbooleantrue
levelstring"error"
no-unescaped-outputerror

This rule ensures that any variable or function call that is output directly to the page is properly escaped. All data must be escaped before printing to prevent Cross-Site Scripting (XSS) vulnerabilities.

此规则需要启用 WordPress 集成。

避免
<?php

// This is a major XSS vulnerability.
echo $_GET['user_comment'];
推荐
<?php

echo esc_html( $user_comment );
?>
<a href="<?php echo esc_url( $user_provided_url ); ?>">Link</a>

选项类型默认值
enabledbooleantrue
levelstring"error"
sensitive-parametererror

Requires that parameters that are likely to contain sensitive information (e.g., passwords) are marked with the #[SensitiveParameter] attribute to prevent accidental logging or exposure.

This rule only applies to PHP 8.2 and later, as the SensitiveParameter attribute was introduced in PHP 8.2.

此规则要求 PHP 8.2.0 或更高版本。

避免
<?php

function login(string $username, string $password): void {
   // ...
}
推荐
<?php

function login(string $username, #[SensitiveParameter] string $password): void {
   // ...
}

选项类型默认值
enabledbooleantrue
levelstring"error"
tainted-data-to-sinkerror

Detects user (tainted) data being passed directly to sink functions or constructs (such as echo, print, or user-defined "log" functions). If these functions emit or store data without sanitization, it could lead to Cross-Site Scripting (XSS) or other injection attacks.


避免
<?php

// This is considered unsafe:
echo $_GET['name'] ?? '';
推荐
<?php

// Properly escape data before using a sink like `echo`
echo htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');

选项类型默认值
enabledbooleantrue
known-sink-functionsarray["printf"]
levelstring"error"
disallowed-functionswarning

Flags calls to functions that are disallowed via rule configuration.

You can specify which functions or extensions should be disallowed through the functions or extensions options. This helps enforce coding standards, security restrictions, or the usage of preferred alternatives.

Each entry can be a simple string or an object with name and optional help:

functions = [
    'eval',
    { name = 'error_log', help = 'Use MyLogger instead.' },
]

避免
<?php

curl_init(); // Error: part of a disallowed extension
推荐
<?php

function allowed_function(): void {
    // ...
}

allowed_function(); // Not flagged

选项类型默认值
enabledbooleantrue
extensionsarray[]
functionsarray[]
levelstring"warning"
disallowed-type-instantiationwarning

Flags direct instantiation of specific types that are disallowed via rule configuration.

This rule helps enforce architectural patterns such as factory methods or provider patterns by preventing direct instantiation of specific classes. This is useful for ensuring consistent configuration, centralizing object creation, and maintaining architectural boundaries.

Each entry can be a simple string or an object with name and optional help:

[linter.rules]
disallowed-type-instantiation = {
    enabled = true,
    types = [
        'HttpService\\Client',
        { name = 'DatabaseConnection', help = 'Use DatabaseFactory::create() instead' },
    ]
}

避免
<?php

// Direct instantiation of disallowed type
$client = new HttpService\Client();

// Another disallowed instantiation
$db = new DatabaseConnection('localhost', 'user', 'pass');
推荐
<?php

// Using factory pattern instead of direct instantiation
$client = ClientProvider::getClient();

选项类型默认值
enabledbooleanfalse
levelstring"warning"
typesarray[]
no-roles-as-capabilitieswarning

This rule flags the use of user roles (e.g., 'administrator') in functions that expect a granular capability (e.g., 'edit_posts'). Checking against specific capabilities is a core security principle in WordPress.

此规则需要启用 WordPress 集成。

避免
<?php

// This check is brittle and will fail if roles are customized.
if ( current_user_can( 'editor' ) ) { /* ... */ }
推荐
<?php

if ( current_user_can( 'edit_posts' ) ) { /* ... */ }

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-short-opening-tagwarning

Disallows the use of short opening tags (<?).

The availability of <? depends on the short_open_tag directive in php.ini. If this setting is disabled on a server, any code within the short tags will be exposed as plain text, which is a significant security risk. Using the full <?php opening tag is the only guaranteed portable way to ensure your code is always interpreted correctly.


避免
<?

echo "Hello, World!";
推荐
<?php

echo "Hello, World!";

选项类型默认值
enabledbooleantrue
levelstring"warning"
require-preg-quote-delimiterwarning

This rule requires that when using preg_quote(), the second $delimiter argument is always provided. If the string being quoted contains the same character used for your regex delimiter (e.g., /), failing to provide the second argument will prevent that character from being escaped, which can break the regular expression.


避免
<?php

// If $user_input contains '/', the regex will be invalid.
$pattern = '/' . preg_quote( $user_input ) . '/';
推荐
<?php

// The delimiter is provided, ensuring it gets escaped if necessary.
$pattern = '/' . preg_quote( $user_input, '/' ) . '/';

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-debug-symbolsnote

Flags calls to debug functions like var_dump, print_r, dd, etc.

These functions are useful for debugging, but they should not be committed to version control as they can expose sensitive information and are generally not intended for production environments.


避免
<?php

function process_request(array $data) {
    var_dump($data); // Debug call that should be removed
    // ...
}
推荐
<?php

// Production-safe code
error_log('Processing user request.');

选项类型默认值
enabledbooleantrue
levelstring"note"

安全性

可以通过编译但运行时会出问题的写法。这些规则在用户遇到之前就揪出陷阱。

no-error-control-operatorerror

Detects the use of the error control operator @.

The error control operator suppresses errors and makes debugging more difficult.


避免
<?php

$result = @file_get_contents('example.txt');
推荐
<?php

try {
    $result = file_get_contents('example.txt');
} catch (Throwable $e) {
    // Handle error
}

选项类型默认值
enabledbooleantrue
levelstring"error"
no-evalerror

Detects unsafe uses of the eval construct. The eval construct executes arbitrary code, which can be a major security risk if not used carefully.


避免
<?php

eval('echo "Hello, world!";');
推荐
<?php

// Safe alternative to eval
$result = json_decode($jsonString);

选项类型默认值
enabledbooleantrue
levelstring"error"
no-ffierror

Detects unsafe use of the PHP FFI (Foreign Function Interface) extension.

The FFI extension allows interaction with code written in other languages, such as C, C++, and Rust. This can introduce potential security risks and stability issues if not handled carefully.

If you are confident in your use of FFI and understand the risks, you can disable this rule in your Mago configuration.


避免
<?php

use FFI;

$ffi = FFI::cdef("void* malloc(size_t size);");
$ffi->malloc(1024); // Allocate memory but never free it
推荐
<?php

// Using a safe alternative to FFI
$data = 'some data';
$hash = hash('sha256', $data);

选项类型默认值
enabledbooleantrue
levelstring"error"
no-globalerror

Detects the use of the global keyword and the $GLOBALS variable.

The global keyword introduces global state into your function, making it harder to reason about and test.


避免
<?php

function foo(): void {
    global $bar;
    // ...
}
推荐
<?php

function foo(string $bar): void {
    // ...
}

选项类型默认值
enabledbooleantrue
levelstring"error"
no-request-variableerror

Detects the use of the $_REQUEST variable, which is considered unsafe.

Use $_GET, $_POST, or $_COOKIE instead for better clarity.


避免
<?php

$identifier = $_REQUEST['id'];
推荐
<?php

$identifier = $_GET['id'];

选项类型默认值
enabledbooleantrue
levelstring"error"
no-shell-execute-stringerror

Detects the use of shell execute strings (...) in PHP code.


避免
<?php

$output = `ls -l`;
推荐
<?php

$output = shell_exec('ls -l');

选项类型默认值
enabledbooleantrue
levelstring"error"
no-unsafe-finallyerror

Detects control flow statements in finally blocks.

Control flow statements in finally blocks override control flows from try and catch blocks, leading to unexpected behavior.


避免
<?php

function example(): int {
    try {
        return get_value();
    } finally {
        return 42; // Unsafe control flow statement in finally block
    }
}
推荐
<?php

function example(): int {
    try {
        return get_value();
    } finally {
        // no control flow statements
    }
}

选项类型默认值
enabledbooleantrue
levelstring"error"
no-request-allwarning

Detects the use of $request->all() or Request::all() in Laravel applications.

Such calls retrieve all input values, including ones you might not expect or intend to handle. It is recommended to use $request->only([...]) to specify the inputs you need explicitly, ensuring better security and validation.

此规则需要启用 Laravel 集成。

避免
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     */
    public function store(Request $request): RedirectResponse
    {
        $data = $request->all();

        // ...
    }
}
推荐
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     */
    public function store(Request $request): RedirectResponse
    {
        $data = $request->only(['name', 'email', 'password']);

        // ...
    }
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-service-state-mutationwarning

Detects mutations to $this->property inside service methods.

In worker-mode PHP runtimes (FrankenPHP, RoadRunner, Swoole), services persist across requests. Mutating $this->property in a service method introduces shared mutable state that leaks between requests, leading to subtle and hard-to-reproduce bugs.

Mutations include direct assignment ($this->count = 0), compound assignment ($this->count += 1), increment/decrement ($this->count++, ++$this->count), array append ($this->items[] = $item), and unset($this->cache).

The __construct and reset methods are allowed by default.

此规则需要启用 Symfony 集成。

避免
<?php

namespace App\Service;

final class InvoiceService
{
    private int $processedCount = 0;

    public function process(Invoice $invoice): void
    {
        $this->processedCount++;
    }
}
推荐
<?php

namespace App\Service;

final class InvoiceService
{
    public function __construct(
        private readonly InvoiceRepository $repository,
    ) {}

    public function process(Invoice $invoice): void
    {
        $total = $invoice->getTotal();
        $this->repository->save($invoice);
    }
}

选项类型默认值
allowed-methodsarray["__construct","reset"]
enabledbooleanfalse
exclude-namespacesarray["App\\Entity\\","App\\DTO\\","App\\ValueObject\\"]
include-namespacesarray["App\\"]
levelstring"warning"
reset-interfacesarray["Symfony\\Contracts\\Service\\ResetInterface"]

正确性

缺陷与逻辑错误。本类规则负责发现作者本意之外的行为。

no-onlyerror

Detects usage of ->only() in Pest tests which should not be committed.

The ->only() modifier causes only that specific test to run, which can lead to incomplete test coverage if accidentally committed to the repository.

此规则需要启用 Pest 集成。

避免
<?php

test('example test', function () {
    expect(true)->toBeTrue();
})->only();

it('does something', function () {
    expect(1)->toBe(1);
})->only();
推荐
<?php

test('example test', function () {
    expect(true)->toBeTrue();
});

it('does something', function () {
    expect(1)->toBe(1);
});

选项类型默认值
enabledbooleantrue
levelstring"error"
assert-descriptionwarning

Detects assert functions that do not have a description.

Assert functions should have a description to make it easier to understand the purpose of the assertion.


避免
<?php

assert($user->isActivated());
推荐
<?php

assert($user->isActivated(), 'User MUST be activated at this point.');

选项类型默认值
enabledbooleantrue
levelstring"warning"
identity-comparisonwarning

Detects equality and inequality comparisons that should use identity comparison operators.


避免
<?php

if ($a == $b) {
    echo '$a is same as $b';
}
推荐
<?php

if ($a === $b) {
    echo '$a is same as $b';
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
ineffective-format-ignore-nextwarning

Detects @mago-format-ignore-next markers that will have no effect.

The formatter's ignore-next marker works at the statement level. When a marker is placed inside an expression (like function call arguments, array elements, or other non-statement contexts), it will not affect the formatter's output.

To effectively ignore the next statement, place the marker immediately before a complete statement at the top level of a block or file.


避免
<?php

// This doesn't work - marker is inside an array literal
$arr = [ // @mago-format-ignore-next
    1,
    2,
];
推荐
<?php

// This works - marker is before a statement
// @mago-format-ignore-next
const GRID = [
  [1, 2, 3], [1, 2, ], [0,    0],
];

foo();

选项类型默认值
enabledbooleantrue
levelstring"warning"
ineffective-format-ignore-regionwarning

Detects @mago-format-ignore-start markers that will have no effect.

The formatter's ignore regions work at the statement level. When an ignore marker is placed inside an expression (like function call arguments, array elements, or other non-statement contexts), it will not affect the formatter's output.

To effectively ignore a region, place the ignore markers between complete statements at the top level of a block or file.


避免
<?php

// This doesn't work - markers are inside a function call
foo( // @mago-format-ignore-start
    $x,
    $y
// @mago-format-ignore-end
);
推荐
<?php

// This works - markers are between statements
// @mago-format-ignore-start
$x = 1;  $y = 2;  // preserved as-is
// @mago-format-ignore-end

foo();

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-assign-in-argumentwarning

Detects assignments in function call arguments which can lead to unexpected behavior and make the code harder to read and understand.


避免
<?php

foo($x = 5);
推荐
<?php

$x = 5;
foo($x);

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-assign-in-conditionwarning

Detects assignments in conditions which can lead to unexpected behavior and make the code harder to read and understand.


避免
<?php

if ($x = 1) {
    // ...
}
推荐
<?php

$x = 1;
if ($x == 1) {
    // ...
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-dead-storewarning

Flags assignments to a variable whose value is overwritten by a later assignment without being read in between. The earlier assignment is dead; its value never reaches anything observable.

Detection is limited to linear (non-branching) flow. Writes inside conditional branches (if/else, loops, match arms, try paths, switch cases) don't pair up with writes in sibling branches, so this rule produces no false positives for code like if ($cond) { $x = 1; } else { $x = 2; } return $x;.

Variables whose name starts with an underscore ($_, $_foo) are ignored. Variables declared via global or static are also ignored.

The rule analyses one function-like scope at a time. It bails out of any scope that uses variable variables ($$x, ${expr}) or calls extract().


避免
<?php

function f() {
    $x = 1; // dead - overwritten before being read
    $x = compute();
    return $x;
}
推荐
<?php

function f() {
    $x = compute();
    return $x;
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-empty-catch-clausewarning

Warns when a catch clause is empty.

An empty catch clause suppresses exceptions without handling or logging them, potentially hiding errors that should be addressed. This practice, known as "exception swallowing," can make debugging significantly more difficult.


避免
<?php

try {
    // some code
} catch(Exception $e) {
    // This block is empty and swallows the exception.
}
推荐
<?php

try {
    // some code that might throw an exception
} catch(Exception $e) {
    // Handle the error, log it, or re-throw it.
    error_log($e->getMessage());
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
no-redundant-variablewarning

Flags variables that are written or declared but whose value is never read.

Detects fully-unused variables (assigned and never referenced) as well as variables whose only mention is on the write side, for example, an undefined name passed to a function as a potential by-reference output where the result is never observed by the caller.

Variables whose name starts with an underscore ($_, $_foo) are treated as intentionally-discarded and are ignored. Variables declared via global or static are also ignored, since they are bindings to external scope.

The rule analyses one function-like scope at a time. It bails out of any scope that uses variable variables ($$x, ${expr}) or calls extract(), since those introduce names the linter cannot resolve.


避免
<?php

function greet(string $name): string
{
    $unused = compute_something();

    return "Hello, $name!";
}
推荐
<?php

function greet(string $name): string
{
    $greeting = "Hello, $name!";

    return $greeting;
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-unused-closure-capturewarning

Flags variables in a closure's use (...) clause that are never read or written inside the closure body.

Captures only earn their keep when the body refers to them. A capture that nothing observes is usually a leftover from a refactor or a typo in the captured name.

Names beginning with an underscore ($_, $_foo) are treated as intentionally-discarded and are ignored. By-reference captures (use (&$x)) are also ignored, they are commonly used for their side-effect on the outer scope, even when the inner body doesn't otherwise touch the binding. The rule bails out of any closure body that uses variable variables ($$x, ${expr}) or calls extract().


避免
<?php

$base = 10;
$add = function (int $x) use ($base): int {
    return $x;
};
推荐
<?php

$base = 10;
$add = function (int $x) use ($base): int {
    return $x + $base;
};

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-unused-globalwarning

Flags global $x; declarations whose name is never read or written inside the surrounding function-like scope.

A global statement only earns its keep when later code refers to the imported binding. If the name is never used, the statement is dead , usually a leftover from a refactor or a typo in the imported name.

Names beginning with an underscore ($_, $_foo) are treated as intentionally-discarded and are ignored. The rule bails out of any scope that uses variable variables ($$x, ${expr}) or calls extract(), since those introduce names the linter cannot resolve.


避免
<?php

function f(): void {
    global $forgotten;
}
推荐
<?php

function bump(): void {
    global $counter;
    $counter++;
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
no-unused-staticwarning

Flags static $x; declarations whose name is never read or written inside the surrounding function-like scope.

A static declaration only earns its keep when later code refers to the binding. If the name is never used after the declaration, the statement is dead, usually a leftover from a refactor.

Names beginning with an underscore ($_, $_foo) are treated as intentionally-discarded and are ignored. The rule bails out of any scope that uses variable variables ($$x, ${expr}) or calls extract(), since those introduce names the linter cannot resolve.


避免
<?php

function f(): void {
    static $forgotten = 0;
}
推荐
<?php

function next_id(): int {
    static $counter = 0;
    return ++$counter;
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
strict-assertionswarning

Detects non-strict assertions in test methods. Assertions should use strict comparison methods, such as assertSame or assertNotSame instead of assertEquals or assertNotEquals.

此规则需要启用 PHPUnit 集成。

避免
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

final class SomeTest extends TestCase
{
    public function testSomething(): void
    {
        $this->assertEquals(42, 42);
    }
}
推荐
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

final class SomeTest extends TestCase
{
    public function testSomething(): void
    {
        $this->assertSame(42, 42);
    }
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
strict-behaviorwarning

Detects functions relying on loose comparison unless the $strict parameter is specified. The use of loose comparison for these functions may lead to hard-to-debug, unexpected behaviors.

此规则要求 PHP 7.0.0 或更高版本。

避免
<?php

in_array(1, ['foo', 'bar', 'baz']);
推荐
<?php

in_array(1, ['foo', 'bar', 'baz'], strict: true);

选项类型默认值
allow-loose-behaviorbooleanfalse
enabledbooleantrue
levelstring"warning"
strict-typeswarning

Detects missing declare(strict_types=1); statement at the beginning of the file.

此规则要求 PHP 7.0.0 或更高版本。

避免
<?php

echo "Hello, World!";
推荐
<?php

declare(strict_types=1);

echo "Hello, World!";

选项类型默认值
allow-disablingbooleanfalse
enabledbooleantrue
levelstring"warning"
switch-continue-to-breakwarning

Detects the use of continue inside a switch statement, which should be break instead.

In PHP, continue inside a switch behaves the same as break, but using continue is misleading because it suggests continuing a loop.


避免
<?php

switch ($value) {
    case 1:
        echo 'one';
        continue;
}
推荐
<?php

switch ($value) {
    case 1:
        echo 'one';
        break;
}

选项类型默认值
enabledbooleanfalse
levelstring"warning"
use-specific-assertionswarning

Suggests using specific PHPUnit assertions instead of generic equality assertions when comparing with null, true, or false.

Using specific assertions like assertNull, assertTrue, and assertFalse provides clearer error messages and makes test intent more explicit.

此规则需要启用 PHPUnit 集成。

避免
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

final class SomeTest extends TestCase
{
    public function testSomething(): void
    {
        $this->assertEquals(null, $value);
        $this->assertSame(true, $flag);
        $this->assertEquals(false, $condition);
    }
}
推荐
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

final class SomeTest extends TestCase
{
    public function testSomething(): void
    {
        $this->assertNull($value);
        $this->assertTrue($flag);
        $this->assertFalse($condition);
    }
}

选项类型默认值
enabledbooleantrue
levelstring"warning"
invalid-open-tagnote

Detects misspelled PHP opening tags like <php? instead of <?php.

A misspelled opening tag will cause the PHP interpreter to treat the following code as plain text, leading to the code being output directly to the browser instead of being executed. This can cause unexpected behavior and potential security vulnerabilities.


避免
<php?

echo 'Hello, world!';
推荐
<?php

echo 'Hello, world!';

选项类型默认值
enabledbooleantrue
levelstring"note"

↳ 编辑此页 →