| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 1 | 19 | 13 | 3% |
| Commands | 1 | 0 | 0 | 100% |
| Section tags | 2 | 3 | 2 | 29% |
What each file covers
Sections
1 shared · 19 only in A · 13 only in B- − PHPStan Blog Writing Style Guide
- − Voice and Tone
- − Article Types and Their Patterns
- − Release Announcements (tag: releases)
- − Guides and Explanations (tag: guides)
- − "Solving PHPStan error..." Series
- − Structure and Formatting
- − Headings
- − Code Examples
- − Footnotes
- − Links
- − Embedded Tweets
- − Markdown Abbreviations
- − Bullet Points
- − Error Messages
- − Images
- − Mermaid Diagrams
- − Standard Closing
- − Content Principles
- + PHPStan Error Identifier Documentation
- + How these files are generated
- + File format
- + Code example
- + Why is it reported?
- + How to fix it
- + "Why is it reported?" section
- + "How to fix it" section
- + Do NOT
- + Identifier prefix reference
- + Prefixes with special identifier format
- + Tone and style
- + Example
- Frontmatter
Commands
1 shared · 0 only in A · 0 only in B- php
Section tags
2 shared · 3 only in A · 2 only in B- − architecture
- − types
- − deployment
- + do-not
- + docs
- lint-format
- code-style
Line diff
phpstan/phpstan · website/src/_posts/CLAUDE.md
@@ −1 @@
1# PHPStan Blog Writing Style Guide
2
3The PHPStan blog is written by Ondrej Mirtes, creator and maintainer of PHPStan. All articles are written in first person singular ("I"). The voice is conversational, technically authoritative, and occasionally humorous.
4
5## Voice and Tone
6
7- **First person**: Always "I", never "we" when referring to the author's decisions (though "we" is okay when referring to the PHPStan project or community collectively, e.g. "we improved BetterReflection").
8- **Casual but knowledgeable**: Uses contractions ("it's", "doesn't", "I'm"), informal phrasing ("gonna", "dtto"), and direct address to the reader ("you").
9- **Confident and opinionated**: Doesn't hedge or equivocate. States positions clearly. e.g. "I'd absolutely avoid inheritance", "the right solutions to both of these reasons are different, and I'm gonna tell you how and why."
10- **Enthusiastic about static analysis**: Genuine excitement about features and improvements. e.g. "I've been looking forward to implementing and releasing the ideas present in PHPStan 1.10 for a long time."
11- **Self-deprecating humor**: Occasional jokes at own expense. e.g. "I automated and scaled my favourite part of being a software developer: pointing out mistakes in other people's code", or footnotes like `[^lovemyjob]: I love my job!`
12- **Emoji usage**: Very rare and restrained. Occasional use in informal contexts.
13- **Explains the "why" before the "how"**: Motivates features by describing the problem they solve, often with real-world scenarios.
14
15## Frontmatter
16
17Every post has YAML frontmatter:
18
19```yaml
20---
21title: "Title in Title Case With Quotes"
22date: YYYY-MM-DD
23tags: releases # or: guides, other
24---
25```
26
27Tags categorize articles:
28- `releases` - Version announcements, new feature introductions
29- `guides` - Explanations, tutorials, problem-solving articles
30- `other` - Website meta, process, non-technical
31
32## Article Types and Their Patterns
33
34### Release Announcements (tag: releases)
35
36Open with context about what makes this release special. Cover headline features with their own `##` sections. Each feature section explains the motivation, shows code examples, and links to documentation or playground. Often credits contributors by name with GitHub links. End with excitement about the future and the standard sponsorship CTA.
37
38Example opening: "PHPStan 1.0 was released a little over three years ago. I'm happy to report the project is thriving! We did about 176 new releases since then..."
39
40### Guides and Explanations (tag: guides)
41
42Start by framing the problem or concept. Walk through solutions or explanations methodically. Heavy use of PHP code examples. Link to relevant documentation pages. Often structured as a series of solutions or approaches.
43
44Example opening: "This error is reported for `new static()` calls that might break once the class is extended, and the constructor is overridden with different parameters."
45
46### "Solving PHPStan error..." Series
47
48Title format: `Solving PHPStan error "Exact error message here"`
49
50These follow a consistent pattern:
511. Brief explanation of what triggers the error
522. Multiple solution sections, each with its own heading
533. Code examples showing the fix (often using `diff-php` syntax)
544. Links to relevant documentation
55
56## Structure and Formatting
57
58### Headings
59
60Use either `##` (H2) or dashed-underline style:
61
62```markdown
63Section title
64------------------------
65```
66
67Both styles are used; dashed underlines are more common in guides, `##` in release announcements.
68
69### Code Examples
70
71- PHP code in ` ```php ` fenced blocks
72- NEON configuration in ` ```neon ` blocks
73- Diff examples use ` ```diff-php ` with `+`/`-` prefixes
74- Bash commands in ` ```bash ` blocks
75- Comments inside code explain what PHPStan reports or what types are inferred
76- Example: `// PHPStan reports: Unsafe usage of new static()`
77- Example: `\PHPStan\dumpType($d); // MyDerivative :)`
78
79### Footnotes
80
81Used liberally for asides, jokes, and tangential notes:
82
83```markdown
84Something important. [^footnote]
85
86[^footnote]: This is a tangential aside or joke.
87```
88
89Examples:
90- `[^lovemyjob]: I love my job!`
91- `[^parcel]: It might as well mean "I can't configure Webpack and I'm not ashamed!"`
92- `[^telemetry]: This is just from my personal experience and anecdotal evidence - PHPStan doesn't perform any telemetry on user's code.`
93
94### Links
95
96- Cross-references to other blog posts: `[Learn more](/blog/article-slug)`
97- Links to documentation: `[configuration](/config-reference)`
98- Playground examples: `[playground example](/r/uuid-here)` or `[Link to this example on the playground](/r/uuid-here)`
99- GitHub releases: `[PHPStan 1.9.0](https://github.com/phpstan/phpstan/releases/tag/1.9.0)`
100- Credit contributors with GitHub profile links
101
102### Embedded Tweets
103
104Used as social proof, community reactions, or to reference prior statements. Full HTML `<blockquote class="twitter-tweet">` embeds with the Twitter widgets script.
105
106### Markdown Abbreviations
107
108Occasionally used for technical acronyms:
109
110```markdown
111*[AST]: Abstract Syntax Tree
112*[OOP]: Object-Oriented Programming
113*[TLC]: Tender Loving Care
114```
115
116### Bullet Points
117
118Used extensively, especially for listing features, solutions, or examples. Concise, often one line each.
119
120### Error Messages
121
122PHPStan error messages are quoted with `>` blockquotes or inline backticks:
123
124```markdown
125> Access to an undefined property Foo::$x.
126```
127
128or
129
130```markdown
131PHPStan reports "string|null is not subtype of native type string"
132```
133
134### Images
135
136Occasionally used for screenshots or diagrams. Format:
137
138```markdown
139
140```
141
142Or with additional HTML/CSS classes for styled presentation.
143
144### Mermaid Diagrams
145
146Used sparingly for flowcharts:
147
148```markdown
149{% mermaid %}
150flowchart LR;
151Node1== label ==>Node2
152{% endmermaid %}
153```
154
155## Standard Closing
156
157Almost every article ends with a horizontal rule and a sponsorship CTA. The exact wording has evolved over time:
158
159Early articles:
160```markdown
161Do you like PHPStan and use it every day? [**Consider supporting further development of PHPStan on GitHub Sponsors**](https://github.com/sponsors/ondrejmirtes/). I'd really appreciate it!
162```
163
164Recent articles:
165```markdown
166Do you like PHPStan and use it every day? [**Consider sponsoring** further development of PHPStan on GitHub Sponsors and also **subscribe to PHPStan Pro**](/sponsor)! I'd really appreciate it!
167```
168
169Most recent:
170```markdown
171Do you like PHPStan and use it every day? [**Consider supporting further development of PHPStan**](/sponsor). I'd really appreciate it!
172```
173
174## Content Principles
175
1761. **Practical over theoretical**: Always show real code examples. Don't just describe - demonstrate.
1772. **Acknowledge tradeoffs**: When explaining design decisions, mention what was considered and why certain approaches were chosen.
1783. **Credit contributors**: Name individuals who contributed features, with links to their GitHub profiles.
1794. **Build on existing content**: Reference and link to previous blog posts and documentation. The blog forms an interconnected knowledge base.
1805. **Progressive disclosure**: Start with the simplest explanation or solution, then build to more complex ones.
1816. **Real-world context**: Use examples from actual frameworks (Doctrine, PHPUnit, Laravel) and real codebases (Adminer, PrestaShop) to ground explanations.
1827. **Don't talk down**: Assume the reader is a competent PHP developer who may not be familiar with type theory or static analysis concepts.
183
phpstan/phpstan · website/errors/CLAUDE.md
@@ +1 @@
1# PHPStan Error Identifier Documentation
2
3This directory contains markdown documentation files for PHPStan error identifiers. Each file explains what a specific error means, shows a triggering code example, and offers ways to fix it.
4
5## How these files are generated
6
7Files are generated by a GitHub Actions workflow (`.github/workflows/generate-error-docs.md`) that uses Claude to:
8
91. Read `website/src/errorsIdentifiers.json` which maps each identifier to its rule classes and source code locations
102. Pick undocumented identifiers (ones without a corresponding `.md` file here)
113. Clone referenced PHPStan repositories (`phpstan-src`, `phpstan-strict-rules`, `phpstan-doctrine`, etc.)
124. Research each identifier by reading rule source code and test fixtures
135. Generate a markdown file for each identifier
14
15## File format
16
17Each file follows this exact structure:
18
19```markdown
20---
21title: "<identifier>"
22shortDescription: "One sentence describing when this error is reported."
23ignorable: true
24---
25
26## Code example
27
28` ``php
29<?php declare(strict_types = 1);
30
31// Minimal PHP code that triggers this error
32` ``
33
34## Why is it reported?
35
36Explanation from PHP language perspective.
37
38## How to fix it
39
40Ways to fix the error.
41```
42
43### Frontmatter
44
45- `title`: The error identifier (e.g., `"property.notFound"`)
46- `shortDescription`: One sentence (ending with a period) describing when the error is reported. Written from a user's perspective — what code pattern causes PHPStan to report this error. Examples: `"Accessing a private property from outside the declaring class."`, `"Loose comparison using == will always evaluate to true."`, `"Pure function uses print, which produces output as a side effect."`
47- `ignorable`: `true` for most identifiers. Set to `false` for identifiers that use `->nonIgnorable()` in the rule builder chain, or that start with `phpstan.` or `phpstanPlayground.`
48
49### Code example
50
51- Must be valid PHP that triggers the identifier
52- Starts with `<?php declare(strict_types = 1);`
53- Uses `php` language tag
54- Keep it minimal — remove unrelated classes, simplify names
55- Prefer real code from test fixtures when possible
56
57### "Why is it reported?" section
58
59- Explain PHP language semantics, not PHPStan internals
60- PHPStan points to code that causes crashes, doesn't execute at all, or doesn't do what the developer probably intended
61- Be concise and technically precise
62- List multiple reasons if applicable
63- If the rule's `->tip()` links to a blog post on phpstan.org, mention it: `Learn more: [Blog post title](/blog/post-slug)`
64
65### "How to fix it" section
66
67- Offer multiple ways to fix when applicable
68- Use `diff-php` syntax for code changes
69- Prefer fixes in this order:
70 1. Fix the actual bug
71 2. Narrow the type using native PHP type declarations
72 3. Narrow the type using PHPDoc types (`@param`, `@return`, `@var` on properties)
73 4. Use [type narrowing](/writing-php-code/narrowing-types) in the function body
74 5. Configure PHPStan if the rule is configurable
75- When the error involves a PHP language feature only available in newer PHP versions, mention the PHPDoc-based alternative that works on older versions too. For example: native return type `never` (PHP 8.1+) can be replaced with `@return never`, native union types (PHP 8.0+) can be expressed as PHPDoc union types, native intersection types (PHP 8.1+) can be expressed as PHPDoc intersection types, standalone types like `true`/`false`/`null` (PHP 8.2+) can be written in PHPDoc. Link to [PHPDoc Basics](/writing-php-code/phpdocs-basics) and [PHPDoc Types](/writing-php-code/phpdoc-types) where relevant.
76- Every time a configuration parameter is mentioned, link it to the correct documentation page. Consult `website/src/config-reference.md` to find the right anchor — parameters that have their own `###` heading (like `phpVersion`) link to `/config-reference#phpversion`. Parameters that only appear as "Related config keys" link to the user guide page referenced there (e.g., `reportUnmatchedIgnoredErrors` links to `/user-guide/ignoring-errors#reporting-unused-ignores`, `scanFiles` links to `/user-guide/discovering-symbols#third-party-code-outside-of-composer-dependencies`).
77- Show code fixes. Use `diff-php` syntax when showing changes:
78
79````markdown
80```diff-php
81- $value = $this->getValue();
82+ $value = (string) $this->getValue();
83```
84````
85
86### Do NOT
87
88- Suggest using `assert()` for type narrowing
89- Suggest throwing an exception to narrow types
90- Suggest using inline `@var` PHPDoc tag
91- Suggest ignoring the error (the detail page already covers that)
92- Use emojis or first person
93
94## Identifier prefix reference
95
96Some prefixes are non-obvious because they come from `ClassNameUsageLocation`:
97
98| Prefix | PHP Feature |
99|--------|-------------|
100| `assert` | `@phpstan-assert` PHPDoc tag (NOT `assert()` function) |
101| `attribute` | PHP 8.0+ attributes `#[AttributeName]` |
102| `catch` | `catch (ExceptionClass $e)` blocks |
103| `classConstant` | `ClassName::CONSTANT` access |
104| `instanceof` | `$x instanceof ClassName` expressions |
105| `methodTag` | `@method` PHPDoc tag |
106| `mixin` | `@mixin` PHPDoc tag |
107| `new` | `new ClassName()` instantiation |
108| `parameter` | Native type declaration on function/method parameter |
109| `property` | Native type declaration on class property (e.g., `private Foo $bar`) |
110| `propertyTag` | `@property` PHPDoc tag |
111| `requireExtends` | `@phpstan-require-extends` PHPDoc tag |
112| `requireImplements` | `@phpstan-require-implements` PHPDoc tag |
113| `return` | Native return type declaration |
114| `sealed` | `@phpstan-sealed` PHPDoc tag |
115| `selfOut` | `@phpstan-self-out` PHPDoc tag |
116| `staticMethod` | `ClassName::method()` static method calls |
117| `staticProperty` | `ClassName::$property` static property access |
118| `traitUse` | `use TraitName` in a class body |
119| `typeAlias` | PHPStan type alias references |
120| `varTag` | `@var` PHPDoc tag |
121
122### Prefixes with special identifier format
123
124| Prefix pattern | PHP Feature |
125|----------------|-------------|
126| `class.extends*` | `class Foo extends ParentClass` |
127| `class.implements*` | `class Foo implements Interface` |
128| `enum.implements*` | `enum Foo implements Interface` |
129| `interface.extends*` | `interface Foo extends OtherInterface` |
130| `generics.*Bound` | `@template T of BoundClass` bound constraint |
131| `generics.*Default` | `@template T = DefaultClass` default value |
132
133## Tone and style
134
135- Concise, technically precise, no filler words
136- Match existing phpstan.org documentation style
137- Direct and practical
138- For extension-specific identifiers (phpstan-doctrine, phpstan-symfony, etc.), mention which extension package provides the rule
139
140## Example
141
142For `website/errors/deadCode.unreachable.md`:
143
144```markdown
145---
146title: "deadCode.unreachable"
147shortDescription: "Code after a return, throw, or other terminating statement can never be executed."
148ignorable: true
149---
150
151## Code example
152
153` ``php
154<?php declare(strict_types = 1);
155
156function doFoo(): int
157{
158 return 1;
159 echo 'unreachable';
160}
161` ``
162
163## Why is it reported?
164
165The statement after `return` can never be executed. The `return` statement unconditionally transfers control out of the function, making any code following it in the same block dead code. This usually indicates a logic error or leftover code from refactoring.
166
167## How to fix it
168
169Remove the unreachable code:
170
171` ``diff-php
172 function doFoo(): int
173 {
174 return 1;
175- echo 'unreachable';
176 }
177` ``
178
179If the code should execute, restructure the logic so it runs before the return:
180
181` ``diff-php
182 function doFoo(): int
183 {
184+ echo 'this should run';
185 return 1;
186- echo 'unreachable';
187 }
188` ``
189```
190
@@ −1 +1 @@
1−# PHPStan Blog Writing Style Guide
1+# PHPStan Error Identifier Documentation
22
3−The PHPStan blog is written by Ondrej Mirtes, creator and maintainer of PHPStan. All articles are written in first person singular ("I"). The voice is conversational, technically authoritative, and occasionally humorous.
3+This directory contains markdown documentation files for PHPStan error identifiers. Each file explains what a specific error means, shows a triggering code example, and offers ways to fix it.
44
5−## Voice and Tone
5+## How these files are generated
66
7−- **First person**: Always "I", never "we" when referring to the author's decisions (though "we" is okay when referring to the PHPStan project or community collectively, e.g. "we improved BetterReflection").
8−- **Casual but knowledgeable**: Uses contractions ("it's", "doesn't", "I'm"), informal phrasing ("gonna", "dtto"), and direct address to the reader ("you").
9−- **Confident and opinionated**: Doesn't hedge or equivocate. States positions clearly. e.g. "I'd absolutely avoid inheritance", "the right solutions to both of these reasons are different, and I'm gonna tell you how and why."
10−- **Enthusiastic about static analysis**: Genuine excitement about features and improvements. e.g. "I've been looking forward to implementing and releasing the ideas present in PHPStan 1.10 for a long time."
11−- **Self-deprecating humor**: Occasional jokes at own expense. e.g. "I automated and scaled my favourite part of being a software developer: pointing out mistakes in other people's code", or footnotes like `[^lovemyjob]: I love my job!`
12−- **Emoji usage**: Very rare and restrained. Occasional use in informal contexts.
13−- **Explains the "why" before the "how"**: Motivates features by describing the problem they solve, often with real-world scenarios.
7+Files are generated by a GitHub Actions workflow (`.github/workflows/generate-error-docs.md`) that uses Claude to:
148
15−## Frontmatter
9+1. Read `website/src/errorsIdentifiers.json` which maps each identifier to its rule classes and source code locations
10+2. Pick undocumented identifiers (ones without a corresponding `.md` file here)
11+3. Clone referenced PHPStan repositories (`phpstan-src`, `phpstan-strict-rules`, `phpstan-doctrine`, etc.)
12+4. Research each identifier by reading rule source code and test fixtures
13+5. Generate a markdown file for each identifier
1614
17−Every post has YAML frontmatter:
15+## File format
1816
19−```yaml
17+Each file follows this exact structure:
18+
19+```markdown
2020 ---
21−title: "Title in Title Case With Quotes"
22−date: YYYY-MM-DD
23−tags: releases # or: guides, other
21+title: "<identifier>"
22+shortDescription: "One sentence describing when this error is reported."
23+ignorable: true
2424 ---
25−```
2625
27−Tags categorize articles:
28−- `releases` - Version announcements, new feature introductions
29−- `guides` - Explanations, tutorials, problem-solving articles
30−- `other` - Website meta, process, non-technical
26+## Code example
3127
32−## Article Types and Their Patterns
28+` ``php
29+<?php declare(strict_types = 1);
3330
34−### Release Announcements (tag: releases)
31+// Minimal PHP code that triggers this error
32+` ``
3533
36−Open with context about what makes this release special. Cover headline features with their own `##` sections. Each feature section explains the motivation, shows code examples, and links to documentation or playground. Often credits contributors by name with GitHub links. End with excitement about the future and the standard sponsorship CTA.
34+## Why is it reported?
3735
38−Example opening: "PHPStan 1.0 was released a little over three years ago. I'm happy to report the project is thriving! We did about 176 new releases since then..."
36+Explanation from PHP language perspective.
3937
40−### Guides and Explanations (tag: guides)
38+## How to fix it
4139
42−Start by framing the problem or concept. Walk through solutions or explanations methodically. Heavy use of PHP code examples. Link to relevant documentation pages. Often structured as a series of solutions or approaches.
40+Ways to fix the error.
41+```
4342
44−Example opening: "This error is reported for `new static()` calls that might break once the class is extended, and the constructor is overridden with different parameters."
43+### Frontmatter
4544
46−### "Solving PHPStan error..." Series
45+- `title`: The error identifier (e.g., `"property.notFound"`)
46+- `shortDescription`: One sentence (ending with a period) describing when the error is reported. Written from a user's perspective — what code pattern causes PHPStan to report this error. Examples: `"Accessing a private property from outside the declaring class."`, `"Loose comparison using == will always evaluate to true."`, `"Pure function uses print, which produces output as a side effect."`
47+- `ignorable`: `true` for most identifiers. Set to `false` for identifiers that use `->nonIgnorable()` in the rule builder chain, or that start with `phpstan.` or `phpstanPlayground.`
4748
48−Title format: `Solving PHPStan error "Exact error message here"`
49+### Code example
4950
50−These follow a consistent pattern:
51−1. Brief explanation of what triggers the error
52−2. Multiple solution sections, each with its own heading
53−3. Code examples showing the fix (often using `diff-php` syntax)
54−4. Links to relevant documentation
51+- Must be valid PHP that triggers the identifier
52+- Starts with `<?php declare(strict_types = 1);`
53+- Uses `php` language tag
54+- Keep it minimal — remove unrelated classes, simplify names
55+- Prefer real code from test fixtures when possible
5556
56−## Structure and Formatting
57+### "Why is it reported?" section
5758
58−### Headings
59+- Explain PHP language semantics, not PHPStan internals
60+- PHPStan points to code that causes crashes, doesn't execute at all, or doesn't do what the developer probably intended
61+- Be concise and technically precise
62+- List multiple reasons if applicable
63+- If the rule's `->tip()` links to a blog post on phpstan.org, mention it: `Learn more: [Blog post title](/blog/post-slug)`
5964
60−Use either `##` (H2) or dashed-underline style:
65+### "How to fix it" section
6166
62−```markdown
63−Section title
64−------------------------
65−```
67+- Offer multiple ways to fix when applicable
68+- Use `diff-php` syntax for code changes
69+- Prefer fixes in this order:
70+ 1. Fix the actual bug
71+ 2. Narrow the type using native PHP type declarations
72+ 3. Narrow the type using PHPDoc types (`@param`, `@return`, `@var` on properties)
73+ 4. Use [type narrowing](/writing-php-code/narrowing-types) in the function body
74+ 5. Configure PHPStan if the rule is configurable
75+- When the error involves a PHP language feature only available in newer PHP versions, mention the PHPDoc-based alternative that works on older versions too. For example: native return type `never` (PHP 8.1+) can be replaced with `@return never`, native union types (PHP 8.0+) can be expressed as PHPDoc union types, native intersection types (PHP 8.1+) can be expressed as PHPDoc intersection types, standalone types like `true`/`false`/`null` (PHP 8.2+) can be written in PHPDoc. Link to [PHPDoc Basics](/writing-php-code/phpdocs-basics) and [PHPDoc Types](/writing-php-code/phpdoc-types) where relevant.
76+- Every time a configuration parameter is mentioned, link it to the correct documentation page. Consult `website/src/config-reference.md` to find the right anchor — parameters that have their own `###` heading (like `phpVersion`) link to `/config-reference#phpversion`. Parameters that only appear as "Related config keys" link to the user guide page referenced there (e.g., `reportUnmatchedIgnoredErrors` links to `/user-guide/ignoring-errors#reporting-unused-ignores`, `scanFiles` links to `/user-guide/discovering-symbols#third-party-code-outside-of-composer-dependencies`).
77+- Show code fixes. Use `diff-php` syntax when showing changes:
6678
67−Both styles are used; dashed underlines are more common in guides, `##` in release announcements.
68−
69−### Code Examples
70−
71−- PHP code in ` ```php ` fenced blocks
72−- NEON configuration in ` ```neon ` blocks
73−- Diff examples use ` ```diff-php ` with `+`/`-` prefixes
74−- Bash commands in ` ```bash ` blocks
75−- Comments inside code explain what PHPStan reports or what types are inferred
76−- Example: `// PHPStan reports: Unsafe usage of new static()`
77−- Example: `\PHPStan\dumpType($d); // MyDerivative :)`
78−
79−### Footnotes
80−
81−Used liberally for asides, jokes, and tangential notes:
82−
83−```markdown
84−Something important. [^footnote]
85−
86−[^footnote]: This is a tangential aside or joke.
79+````markdown
80+```diff-php
81+- $value = $this->getValue();
82++ $value = (string) $this->getValue();
8783 ```
84+````
8885
89−Examples:
90−- `[^lovemyjob]: I love my job!`
91−- `[^parcel]: It might as well mean "I can't configure Webpack and I'm not ashamed!"`
92−- `[^telemetry]: This is just from my personal experience and anecdotal evidence - PHPStan doesn't perform any telemetry on user's code.`
86+### Do NOT
9387
94−### Links
88+- Suggest using `assert()` for type narrowing
89+- Suggest throwing an exception to narrow types
90+- Suggest using inline `@var` PHPDoc tag
91+- Suggest ignoring the error (the detail page already covers that)
92+- Use emojis or first person
9593
96−- Cross-references to other blog posts: `[Learn more](/blog/article-slug)`
97−- Links to documentation: `[configuration](/config-reference)`
98−- Playground examples: `[playground example](/r/uuid-here)` or `[Link to this example on the playground](/r/uuid-here)`
99−- GitHub releases: `[PHPStan 1.9.0](https://github.com/phpstan/phpstan/releases/tag/1.9.0)`
100−- Credit contributors with GitHub profile links
94+## Identifier prefix reference
10195
102−### Embedded Tweets
96+Some prefixes are non-obvious because they come from `ClassNameUsageLocation`:
10397
104−Used as social proof, community reactions, or to reference prior statements. Full HTML `<blockquote class="twitter-tweet">` embeds with the Twitter widgets script.
98+| Prefix | PHP Feature |
99+|--------|-------------|
100+| `assert` | `@phpstan-assert` PHPDoc tag (NOT `assert()` function) |
101+| `attribute` | PHP 8.0+ attributes `#[AttributeName]` |
102+| `catch` | `catch (ExceptionClass $e)` blocks |
103+| `classConstant` | `ClassName::CONSTANT` access |
104+| `instanceof` | `$x instanceof ClassName` expressions |
105+| `methodTag` | `@method` PHPDoc tag |
106+| `mixin` | `@mixin` PHPDoc tag |
107+| `new` | `new ClassName()` instantiation |
108+| `parameter` | Native type declaration on function/method parameter |
109+| `property` | Native type declaration on class property (e.g., `private Foo $bar`) |
110+| `propertyTag` | `@property` PHPDoc tag |
111+| `requireExtends` | `@phpstan-require-extends` PHPDoc tag |
112+| `requireImplements` | `@phpstan-require-implements` PHPDoc tag |
113+| `return` | Native return type declaration |
114+| `sealed` | `@phpstan-sealed` PHPDoc tag |
115+| `selfOut` | `@phpstan-self-out` PHPDoc tag |
116+| `staticMethod` | `ClassName::method()` static method calls |
117+| `staticProperty` | `ClassName::$property` static property access |
118+| `traitUse` | `use TraitName` in a class body |
119+| `typeAlias` | PHPStan type alias references |
120+| `varTag` | `@var` PHPDoc tag |
105121
106−### Markdown Abbreviations
122+### Prefixes with special identifier format
107123
108−Occasionally used for technical acronyms:
124+| Prefix pattern | PHP Feature |
125+|----------------|-------------|
126+| `class.extends*` | `class Foo extends ParentClass` |
127+| `class.implements*` | `class Foo implements Interface` |
128+| `enum.implements*` | `enum Foo implements Interface` |
129+| `interface.extends*` | `interface Foo extends OtherInterface` |
130+| `generics.*Bound` | `@template T of BoundClass` bound constraint |
131+| `generics.*Default` | `@template T = DefaultClass` default value |
109132
110−```markdown
111−*[AST]: Abstract Syntax Tree
112−*[OOP]: Object-Oriented Programming
113−*[TLC]: Tender Loving Care
114−```
133+## Tone and style
115134
116−### Bullet Points
135+- Concise, technically precise, no filler words
136+- Match existing phpstan.org documentation style
137+- Direct and practical
138+- For extension-specific identifiers (phpstan-doctrine, phpstan-symfony, etc.), mention which extension package provides the rule
117139
118−Used extensively, especially for listing features, solutions, or examples. Concise, often one line each.
140+## Example
119141
120−### Error Messages
142+For `website/errors/deadCode.unreachable.md`:
121143
122−PHPStan error messages are quoted with `>` blockquotes or inline backticks:
123−
124144 ```markdown
125−> Access to an undefined property Foo::$x.
126−```
145+---
146+title: "deadCode.unreachable"
147+shortDescription: "Code after a return, throw, or other terminating statement can never be executed."
148+ignorable: true
149+---
127150
128−or
151+## Code example
129152
130−```markdown
131−PHPStan reports "string|null is not subtype of native type string"
132−```
153+` ``php
154+<?php declare(strict_types = 1);
133155
134−### Images
156+function doFoo(): int
157+{
158+ return 1;
159+ echo 'unreachable';
160+}
161+` ``
135162
136−Occasionally used for screenshots or diagrams. Format:
163+## Why is it reported?
137164
138−```markdown
139−
140−```
165+The statement after `return` can never be executed. The `return` statement unconditionally transfers control out of the function, making any code following it in the same block dead code. This usually indicates a logic error or leftover code from refactoring.
141166
142−Or with additional HTML/CSS classes for styled presentation.
167+## How to fix it
143168
144−### Mermaid Diagrams
169+Remove the unreachable code:
145170
146−Used sparingly for flowcharts:
171+` ``diff-php
172+ function doFoo(): int
173+ {
174+ return 1;
175+- echo 'unreachable';
176+ }
177+` ``
147178
148−```markdown
149−{% mermaid %}
150−flowchart LR;
151−Node1== label ==>Node2
152−{% endmermaid %}
153−```
179+If the code should execute, restructure the logic so it runs before the return:
154180
155−## Standard Closing
156−
157−Almost every article ends with a horizontal rule and a sponsorship CTA. The exact wording has evolved over time:
158−
159−Early articles:
160−```markdown
161−Do you like PHPStan and use it every day? [**Consider supporting further development of PHPStan on GitHub Sponsors**](https://github.com/sponsors/ondrejmirtes/). I'd really appreciate it!
181+` ``diff-php
182+ function doFoo(): int
183+ {
184++ echo 'this should run';
185+ return 1;
186+- echo 'unreachable';
187+ }
188+` ``
162189 ```
163−
164−Recent articles:
165−```markdown
166−Do you like PHPStan and use it every day? [**Consider sponsoring** further development of PHPStan on GitHub Sponsors and also **subscribe to PHPStan Pro**](/sponsor)! I'd really appreciate it!
167−```
168−
169−Most recent:
170−```markdown
171−Do you like PHPStan and use it every day? [**Consider supporting further development of PHPStan**](/sponsor). I'd really appreciate it!
172−```
173−
174−## Content Principles
175−
176−1. **Practical over theoretical**: Always show real code examples. Don't just describe - demonstrate.
177−2. **Acknowledge tradeoffs**: When explaining design decisions, mention what was considered and why certain approaches were chosen.
178−3. **Credit contributors**: Name individuals who contributed features, with links to their GitHub profiles.
179−4. **Build on existing content**: Reference and link to previous blog posts and documentation. The blog forms an interconnected knowledge base.
180−5. **Progressive disclosure**: Start with the simplest explanation or solution, then build to more complex ones.
181−6. **Real-world context**: Use examples from actual frameworks (Doctrine, PHPUnit, Laravel) and real codebases (Adminer, PrestaShop) to ground explanations.
182−7. **Don't talk down**: Assume the reader is a competent PHP developer who may not be familiar with type theory or static analysis concepts.
183190
