You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Too Many Arguments Rule](docs/rules/Too-Many-Arguments-Rule.md)
43
46
-[Max Line Length Rule](docs/rules/Max-Line-Length-Rule.md)
44
47
@@ -50,7 +53,7 @@ The rules in this package can be extended at project level to create self-docume
50
53
51
54
A lot of the rules use regex patterns to match things. Many people are not good at writing them but thankfully there is AI today.
52
55
53
-
If you struggle to write the regex patterns you need, you can use AI tools like [ChatGPT](https://chat.openai.com/) to help you generate them. Just describe what you want to match, and it can provide you with a regex pattern that fits your needs. The regex can be tested using online tools like [regex101](https://regex101.com/).
56
+
If you struggle to write the regex patterns you need, you can use AI agents to help you generate them. Just describe what you want to match, and it can provide you with a regex pattern that fits your needs. The regex can be tested using online tools like [regex101](https://regex101.com/).
Copy file name to clipboardExpand all lines: docs/Rules.md
+46Lines changed: 46 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,12 +22,24 @@ Forbids public and/or protected getters and setters on classes matching specifie
22
22
23
23
See [Forbidden Accessors Rule documentation](rules/Forbidden-Accessors-Rule.md) for detailed information.
24
24
25
+
## Forbidden Business Logic Rule
26
+
27
+
Forbids configured control structures (`if`, `for`, `foreach`, `while`, `switch`) inside class methods. A global `forbiddenStatements` list applies to all such methods; optional `patterns` (regex on `Fqcn::methodName`) may supply `forbiddenStatements` per match, which replace the effective list for that method (last matching override wins).
28
+
29
+
See [Forbidden Business Logic Rule documentation](rules/Forbidden-Business-Logic-Rule.md) for detailed information.
30
+
25
31
## Forbidden Dependencies Rule
26
32
27
33
Enforces dependency constraints between namespaces by checking `use` statements and optionally fully qualified class names (FQCNs). This rule prevents classes in one namespace from depending on classes in another, helping enforce architectural boundaries like layer separation.
28
34
29
35
See [Forbidden Dependencies Rule documentation](rules/Forbidden-Dependencies-Rule.md) for detailed information.
30
36
37
+
## Forbidden Date Time Comparison Rule
38
+
39
+
Forbids `===` and `!==` when both sides are definitely `DateTimeInterface`, because strict equality is object identity, not same instant. Optional `patterns` (regex on `Fqcn::methodName`) limit the rule to matching class methods; an empty `patterns` list applies globally (unlike Forbidden Else Statements Rule, where empty `patterns` disables the rule).
40
+
41
+
See [Forbidden Date Time Comparison Rule documentation](rules/Forbidden-Date-Time-Comparison-Rule.md) for detailed information.
42
+
31
43
## Forbidden Static Methods Rule
32
44
33
45
Forbids specific static method calls matching regex patterns. Supports namespace-level, class-level, and method-level granularity. The rule resolves `self`, `static`, and `parent` keywords to actual class names.
@@ -40,6 +52,12 @@ Ensures that classes matching specified patterns have properties with expected n
40
52
41
53
See [Property Must Match Rule documentation](rules/Property-Must-Match-Rule.md) for detailed information.
42
54
55
+
## Forbidden Else Statements Rule
56
+
57
+
Forbids plain `else` in class methods whose `Full\Class\Name::methodName` matches any configured regex, using the same `Fqcn::methodName` convention as other method-scoped rules. Empty `patterns` disables the rule.
58
+
59
+
See [Forbidden Else Statements Rule documentation](rules/Forbidden-Else-Statements-Rule.md) for detailed information.
60
+
43
61
## Full Configuration Example
44
62
45
63
Here is a full example for a modular monolith with clean architecture rules.
@@ -246,6 +264,25 @@ services:
246
264
tags:
247
265
- phpstan.rules.rule
248
266
267
+
# Forbid selected control structures (global + optional per-regex overrides)
Forbids selected imperative control structures inside class methods: `if`, `for`, `foreach`, `while`, and `switch`. Typical use cases include pushing branching and iteration behind domain objects or policy objects in specific layers.
4
+
5
+
The rule evaluates the current scope as `Full\Class\Name::methodName` (from PHPStan’s class and function reflections). Anonymous functions and global functions are out of scope when the class or function reflection is missing.
6
+
7
+
## Global list and per-pattern overrides
8
+
9
+
-**`forbiddenStatements`**: Default set of construct names to forbid in every class method. Names are case-insensitive. Unknown names are ignored. If this list is empty, nothing is forbidden unless a matching pattern entry supplies a non-empty `forbiddenStatements` list.
10
+
-**`patterns`**: Ordered list of entries. Each entry has a **`pattern`** (regex matched against `Fqcn::methodName`). Optionally **`forbiddenStatements`**: if present on an entry whose pattern matches, it **replaces** the effective forbidden list entirely for that method. If several entries match, the **last** matching entry that defines `forbiddenStatements` wins. Entries that match but omit `forbiddenStatements` do not change the effective list (it stays as set by global and earlier matches).
11
+
12
+
The default constructor uses all five constructs globally and an empty `patterns` list, which forbids those constructs everywhere in class methods.
13
+
14
+
## Legacy `patterns` format
15
+
16
+
You may pass plain regex strings; each is normalised to `{ pattern: "..." }` without an override, so only the global list applies for methods that do not receive a later matching override with `forbiddenStatements`.
-`forbiddenStatements` (`list<string>`): Global list of forbidden construct names: `if`, `for`, `foreach`, `while`, `switch`.
47
+
-`patterns` (`list<array{pattern: string, forbiddenStatements?: list<string>}> | list<string>`): Regex entries against `Fqcn::methodName`, optionally with per-entry `forbiddenStatements` that replace the effective list when that pattern matches (last such match wins).
48
+
49
+
## Class-wide patterns
50
+
51
+
Match every method on a class with a regex on the `::` prefix, for example `/^App\\\\Module\\\\Foo::/` or `/^App\\\\Module\\\\Foo::.+$/`.
52
+
53
+
## Ignoring violations
54
+
55
+
Use PHPStan baseline or inline `@phpstan-ignore` with a short justification when a rare exception is required.
0 commit comments