Correctly inferred types, automatic inspections, and how it interacts with PHPStan
Hand-written PHPDoc blocks are almost guaranteed to go stale as soon as a signature changes. PhpStorm can infer docblocks from the actual code, flag outdated comments, and create the foundation PHPStan needs to analyze reliably.
Table of Contents
- 1. Why PHPDoc still matters despite native types
- 2. Letting PhpStorm auto-generate PHPDoc blocks
- 3. Inferring precise types for arrays and collections
- 4. Inspections for missing and outdated PHPDoc comments
- 5. Uncovering project-wide PHPDoc gaps with code inspection
- 6. How PHPDoc and PHPStan typing work together
- 7. Live templates for recurring PHPDoc patterns
- 8. Keeping PHPDoc in sync during refactorings
- 9. PHPDoc completeness as part of the review workflow
- 10. Summary
- 11. FAQ
1. Why PHPDoc still matters despite native types
Since PHP 8, a lot of type information can be expressed directly in the signature: union types, nullable types, even intersection types since PHP 8.1. Still, PHPDoc remains indispensable because native PHP types cannot express generic collections like array
Especially with the project standard of PHPStan at level 5, PHPDoc is not optional decoration, it is the only source from which PHPStan pulls precise array-shape and generics information. If the @return tag with the correct element type is missing, PHPStan falls back to mixed and loses exactly the type information it was supposed to check. PHPDoc and static analysis are two sides of the same coin.
2. Letting PhpStorm auto-generate PHPDoc blocks
PhpStorm generates a PHPDoc block as soon as you type /** above a method or class definition and press Enter. The IDE reads the actual signature: parameter names, declared types, and the return type get inserted automatically as @param and @return lines, without having to type them by hand.
For constructors using constructor property promotion, mandatory for all new classes under the project standard, PhpStorm recognizes the promoted properties and correctly carries their types into the generated block. This is especially valuable because promoted properties are otherwise easily forgotten when adding PHPDoc purely by hand.
/**
* Loads product data for a given SKU.
*
* @param string $sku The product SKU.
* @param StoreInterface $store The current store context.
* @return ProductInterface
* @throws NoSuchEntityException
*/
public function loadProduct(string $sku, StoreInterface $store): ProductInterface
{
// ...
}
3. Inferring precise types for arrays and collections
The auto-generated block produces correct results immediately for simple types like string or ProductInterface. For arrays, plain signature analysis is not enough, since PHP internally only knows array, not array
In practice it is still worth reviewing the generated suggestion and manually sharpening it when needed, for example using array
/**
* Returns all active products of the category.
*
* @return ProductInterface[]
*/
public function getActiveProducts(): array
{
return array_filter(
$this->collection->getItems(),
static fn (ProductInterface $product): bool => $product->getStatus() === 1
);
}
4. Inspections for missing and outdated PHPDoc comments
Under Settings > Editor > Inspections > PHP > PHPDoc there is a set of enableable checks, including 'Missing PHPDoc comment', 'Missing @param tag', 'Missing @return tag', and 'Incorrect PHPDoc'. Given the project standard that requires PHPDoc for every public, protected, and private method, it is worth setting these inspections to Warning or even Error instead of leaving them at the default level.
Particularly valuable is 'Incorrect PHPDoc', because this inspection actively compares against the real signature: if a parameter type changes without the corresponding @param tag being updated, PhpStorm flags the line as an error right away. This prevents the most common PHPDoc problem in mature codebases, comments that describe a long-outdated signature and thereby actively mislead.
5. Uncovering project-wide PHPDoc gaps with code inspection
For an existing codebase where PHPDoc has only been maintained sporadically, the per-method view is too slow. Here Code > Inspect Code with a profile restricted to the PHPDoc category helps, listing every affected file in app/code/Mironsoft in a single pass.
The result appears as a sortable list in the Inspection tool window, grouped by file and inspection type. For a new module it is worth running this right after the first draft of a class, before the code goes into review, because missing @throws tags for methods that can throw a NoSuchEntityException surface before a reviewer has to add them manually.
Code > Inspect Code...
Scope: app/code/Mironsoft
Profile: Custom (only PHPDoc inspections enabled)
Result in the Inspection window:
- 12x Missing @throws tag
- 4x Incorrect PHPDoc (outdated parameter type)
- 7x Missing PHPDoc comment (private methods)
6. How PHPDoc and PHPStan typing work together
PHPStan reads PHPDoc comments as an additional type source alongside native PHP types and combines both into the most precise type information possible. If PHPDoc and the native signature contradict each other, for instance because the @return tag declares a different type than the actual return statement, PHPStan already reports an error at level 5. PhpStorm and PHPStan effectively check the same consistency, just at different points in time: PhpStorm while typing, PHPStan as an explicit analysis run.
For the known Magento interface gaps from the project standard, such as PageInterface::getData() or StoreInterface::getBaseUrl(), PHPDoc alone is not enough because the method is simply missing from the interface. Here @phpstan-ignore-next-line remains the right solution, PHPDoc should still document the actually returned type in these cases so IDE autocompletion stays correct even though PHPStan ignores the line.
/** @var \Magento\Cms\Model\Page $page */
$page = $this->pageRepository->getById($pageId);
// @phpstan-ignore-next-line getData() is not on PageInterface, but exists on the model
$metaTitle = $page->getData('meta_title');
7. Live templates for recurring PHPDoc patterns
For frequently recurring docblock patterns, for instance ViewModel classes that always implement ArgumentInterface and always document a getData()-like method with @return array
In practice it pays off to keep a dedicated live template set per recurring pattern: one for repository methods with typical @throws combinations, one for ViewModel constructors using constructor property promotion, one for plugin methods with the usual before, around, or after prefix. This saves the team typing effort and also produces a more consistent PHPDoc structure across all modules.
8. Keeping PHPDoc in sync during refactorings
An often overlooked benefit: when PhpStorm renames a parameter through a refactoring or extracts a method, the IDE frequently updates the associated PHPDoc block automatically as well. During rename refactorings of parameters, the @param name is carried along, during change-signature refactorings new parameters are added as additional @param lines and removed parameters are deleted from the block.
This works reliably enough to noticeably reduce manual maintenance effort, but it does not replace a final check. For more complex refactorings, for instance when a method is split into two, it is worth taking a quick look at the Incorrect PHPDoc inspection afterward to make sure no orphaned @param lines remain for long-removed parameters.
9. PHPDoc completeness as part of the review workflow
So that the project rule 'every method needs PHPDoc' does not depend on individual developer discipline, a combination of local inspection in PhpStorm and a CI step running phpcs with a doc-comment sniff rule such as Squiz.Commenting.FunctionComment is recommended. That way missing or incorrect PHPDoc is not first discovered by a human in review, but already by the IDE before the push and automatically in the pipeline afterward.
In practice it has proven useful to establish the Inspect Code run from the previous section as a fixed step before every pull request, combined with bin/phpcs as a fast command-line check right in the container. Teams that use both layers consistently reduce PHPDoc rework in review to rare edge cases instead of a recurring comment.
| Tool | Purpose | When | Location in PhpStorm |
|---|---|---|---|
| Docblock generation | Generate PHPDoc with types from the signature | While writing new methods | /** + Enter above the method |
| Incorrect PHPDoc | Find mismatches between docblock and signature | While editing | Settings > Inspections > PHP > PHPDoc |
| Inspect Code (batch) | List project-wide PHPDoc gaps | Before pull requests | Code > Inspect Code |
| PHPStan level 5 | Automatically check type consistency | In the CI pipeline | bin/analyse --level=5 |
Mironsoft
PhpStorm setup, Docker integration, and team productivity
PhpStorm that actually runs optimally for Magento and PHP projects?
We review existing PhpStorm setups for slow indexing, unused Docker integration, and missing team conventions, then set up a configuration that is productive from the first second.
Setup Review
Optimizing indexing, interpreter, and memory settings for large Magento projects.
Docker Integration
Cleanly connecting Xdebug, PHPUnit, and database tools to the Docker setup.
Team Conventions
Standardizing inspection profiles, code style, and live templates project-wide.
10. Summary
PHPDoc Automation in PhpStorm: Key Takeaways
Generation
/** + Enter creates a docblock with correctly inferred parameter and return types
Inspection
Incorrect PHPDoc detects mismatches between the comment and the actual signature
PHPStan link
PHPDoc supplies the array-shape and generics information native types cannot express
Team safeguard
Inspect Code runs plus a phpcs sniff prevent PHPDoc from decaying over time