Download the PHP package sanmai/phpstan-rules without Composer
On this page you can find all versions of the php package sanmai/phpstan-rules. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download sanmai/phpstan-rules
More information about sanmai/phpstan-rules
Files in sanmai/phpstan-rules
Package phpstan-rules
Short Description Custom PHPStan rules for enforcing code quality standards
License Apache-2.0
Informations about the package phpstan-rules
sanmai/phpstan-rules
A collection of opinionated PHPStan rules focused on enforcing functional programming patterns and reducing complexity. These rules are tailored specifically to the kind of code LLMs are prone to produce.
Philosophy
These rules encourage:
- Functional programming patterns over imperative nested structures
- Early returns and guard clauses for better readability
- Reduced cyclomatic complexity through flatter code structures
- Explicit code flow that's easier to test and maintain
These principles align well with libraries like sanmai/pipeline
that provide functional programming patterns as alternatives to nested loops.
My rules are designed to work together without creating "whack-a-mole" scenarios. When multiple rules could apply to the same code pattern, they all trigger simultaneously, showing you the complete picture upfront. For example, a function ending with if-else will trigger all matching rules, guiding you directly to the guard clause rather than making you fix one issue only to discover another. This approach helps you fix all violations in a single pass.
Installation
If you also install phpstan/extension-installer
then you're all set!
Manual Installation
If you don't want to use phpstan/extension-installer
, include the extension in your project's phpstan.neon
:
Rules
NoNestedLoopsRule
Prevents nested loops within the same function scope.
This rule encourages extracting nested loops into separate methods or using functional approaches like array_map()
, array_filter()
, or the sanmai/pipeline
library.
Bad
Good - Using sanmai/pipeline
NoNestedIfStatementsRule
Discourages simple nested if statements without else branches.
This rule promotes combining conditions with logical operators or using guard clauses for flatter code structure.
Bad
Good - Combined conditions
Good - Guard clauses
RequireGuardClausesRule
Enforces the use of guard clauses in loops instead of wrapping the main logic in if statements.
This rule encourages early returns/continues to reduce nesting and improve readability.
Exception: Loops where the if statement contains only return
, yield
, yield from
, or throw
statements are allowed, as these are common patterns for filtering/searching operations.
Bad - Loop with only if
Good - Guard clause
Good - If with other statements (allowed)
NoElseRule
Forbids the use of else
statements.
This rule enforces the use of early returns and guard clauses instead of else
branches, leading to flatter and more readable code.
Bad
Good
NoEmptyRule
Forbids the use of the empty()
function (except on nullable arrays).
This rule encourages more explicit checks instead of the ambiguous empty()
function, which can hide bugs and make code harder to understand. The only exception is nullable arrays (?array
) where empty()
provides a cleaner syntax than $items === null || $items === []
.
Bad
Good
NoEmptyOnStringsRule
Forbids the use of empty()
on string types with a specific warning about the '0'
gotcha.
This rule specifically targets string types and mixed types (which could contain strings) to warn about the dangerous behavior where empty('0')
returns true
. This has caused real bugs in production systems where users couldn't search for "0" or use "0" as a valid input.
Bad
Good
RequireGuardClausesInFunctionsRule
Requires guard clauses in functions/methods that end with a single large if statement.
This rule detects functions with void return types (or no return type) that end with a single if
statement containing the main logic. These should be refactored to use guard clauses with early returns, reducing nesting and improving readability.
Bad
Good
This rule only applies to functions with void
return type or no return type. Functions that declare specific return types are exempt, for now.
NoCountZeroComparisonRule
Forbids comparing count()
with 0.
This rule encourages using direct array comparisons (=== []
or !== []
) instead of counting elements, which is more efficient and clearer.
Bad
Good
NoFinalClassesRule
Prevents the use of final
keyword on classes.
This rule discourages final classes as they often create more problems than they solve, especially for testing and mocking. The @final
annotation provides the same benefits by preventing extension via static analysis without the runtime restrictions that interfere with testing and lead to indirection hell.
Bad
Good
This rule only applies to classes. To turn off this rule for specific classes, you can use PHPStan's annotation:
If you'd rather use dg/bypass-finals
for testing, you can turn off this rule entirely by adding the following to your phpstan.neon
:
NoPublicStaticMethodsRule
Allows only one public static method per class.
Static methods are impossible to mock in tests, making code harder to test. This rule limits classes to at most one public static method to encourage dependency injection.
Bad
Good
PHPUnit tests and test cases are excluded.
Ignoring Rules
Please refer to the PHPStan documentation.
Contributing
Found a bug or have a suggestion? Please open an issue.