carthage-software/mago
Mago is an extremely fast PHP linter, formatter, and static analyzer written in Rust. It helps teams catch issues early, enforce consistent style, and improve code quality across projects, with multiple install options like script, Homebrew, Composer, and Cargo.
+++ title = "规则" description = "全部 linter 规则的参考文档,按严重级别排序。点击任意规则可展开其描述、示例和配置。" nav_order = 70 nav_section = "Tools" nav_subsection = "Linter" +++ Mago 的 linter 共提供 176 条规则,分布在 9 个类别中。点击任意规则可展开其描述、要求、默认配置和示例。
部分规则只有在 Mago 检测到特定的库或框架时才会触发。每条规则都链接到上方章节中的完整描述。
psl-array-functionspsl-data-structurespsl-datetimepsl-math-functionspsl-outputpsl-randomness-functionspsl-regex-functionspsl-sleep-functionspsl-string-functionsno-db-schema-changeno-direct-db-queryno-roles-as-capabilitiesno-unescaped-outputuse-wp-functions让意图更明确、减少阅读负担的规则。它们指出在技术上合法但会模糊代码意图的写法。
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 === []) {
// ...
}
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"error" |
Detects implicit octal numeral notation and suggests replacing it with explicit octal numeral notation.
<?php
$a = 0123;
<?php
$a = 0o123;
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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
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 '';
}
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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
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-argument |
boolean |
false |
enabled |
boolean |
true |
level |
string |
"warning" |
threshold |
number |
1 |
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 {}
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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-checks |
boolean |
false |
enabled |
boolean |
true |
level |
string |
"warning" |
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;
class="rule-example__label">推荐
<?php
$b = 0;
$a = $b;
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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();
}
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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;
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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'
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
Enforces using underscore separators in numeric literals for improved readability.
<?php
$a = 1000000;
$b = 0xCAFEF00D;
$c = 0b01011111;
<?php
$a = 1_000_000;
$b = 0xCAFE_F00D;
$c = 0b0101_1111;
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
min-digits |
number |
5 |
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
$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';
}
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
Detects strpos($a, $b) === 0 comparisons and suggests replacing them with str_starts_with($a, $b)
for improved readability and intent clarity.
<?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';
}
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
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](https://github.com/azjezz)) This is a valid FIXME comment.
// FIXME(azjezz) This is a valid FIXME comment.
// FIXME(#123) This is a valid FIXME comment.
| 选项 | 类型 | 默认值 |
|---|---|---|
enabled |
boolean |
true |
level |
string |
"warning" |
How can I help you explore Laravel packages today?