Migrate Doctrine Entities to PHP 8 Attributes with PhpStorm Intentions Without Docblock Drift
PhpStorm parses PHP 8 attributes as code, enabling navigation, refactoring and an intention to convert Doctrine docblock annotations to #[ORM\Entity] attributes. Version and library compatibility matter before bulk migration.
20 Aug 2026, 14:08 UTC

Docblock annotations look fine until they drift. A property gets renamed but /** @ORM\Column(name="old") */ stays behind, and the IDE cannot see the mismatch because annotations are comments. PHP 8 attributes are real code, and PhpStorm treats them as code when the project is configured for PHP 8.0+. That changes navigation, refactoring and migration from annotation to attribute from a manual search-replace into an IDE-guided edit.
The editing model changes with attributes
Attributes are PHP language constructs introduced in PHP 8.0, written as #[ClassName(args)] and attached to classes, properties, methods, functions and parameters. Because they are parsed, PhpStorm can highlight syntax errors, navigate to the attribute class with Ctrl/Cmd+Click, find usages, and run attribute-aware refactorings such as Rename attribute class and safe removal.
The practical benefit is static analysis. A misspelled attribute name or an invalid argument is reported in real time, whereas a typo in a docblock is invisible to the parser. Attribute targets are also enforced, so the IDE can warn when an attribute is used on an unsupported element.
What PhpStorm needs to understand attributes
Reliable support requires two version assumptions. The PhpStorm build must be 2020.3 or newer, and the project PHP language level must be 8.0 or higher. The language level is set in Settings > PHP > Language level. Without it, attributes are treated as unknown syntax and inspections are disabled.
For common frameworks PhpStorm ships with recognition for attribute targets like class, property and method. Third-party attribute libraries or custom targets may need stubs or plugin support for full completion. When stubs are missing, navigation and argument completion can be incomplete.
Worked example: Doctrine ORM entity migration
Consider a Doctrine ORM entity that still uses docblocks:
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private int $id;
}With PHP language level 8.0+ and a Doctrine version that supports attributes, PhpStorm offers an intention to convert annotations to attributes. In the editor, place the caret on a supported PHPDoc annotation and press Alt+Enter. If the Convert to attribute intention appears, apply it. The IDE rewrites the structure while preserving argument names and values for supported libraries, producing attribute syntax such as:
#[ORM\Entity]
#[ORM\Table(name: "users")]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: "integer")]
private int $id;
}After the change, verify navigation by Ctrl/Cmd+Clicking ORM\Entity to the class declaration, and trigger inspections to check for unresolved attributes or missing imports. Completion for attribute arguments should appear when the caret is inside the brackets.
Trade-offs and limits
Converting annotations to attributes is a code-changing operation. Runtime behavior changes if the underlying library version does not support attributes. Verify library compatibility before bulk migration.
Attribute support is version-sensitive. Older PhpStorm builds treat attributes as unknown syntax. Custom attribute libraries may not be fully recognized without proper stubs, leading to incomplete completion and find usages.
Attributes are not a drop-in replacement for every docblock. Some documentation-only annotations have no attribute equivalent. The intention only appears for supported mappings.
Checklist before bulk migration
- Confirm PhpStorm build is 2020.3 or newer via Help > About.
- Open Settings > PHP > Language level and confirm the project is set to 8.0 or higher.
- Verify the target library version supports attributes and check its migration guide.
- Test the Convert to attribute intention on a single file, inspect the resulting code for correct syntax and imports.
- Run existing tests and static analysis after migration to catch runtime differences.
When the project is correctly configured, attributes let PhpStorm treat mapping metadata as real code. That reduces docblock drift and makes rename and navigation safe, but only after confirming version support and library compatibility.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.