name: php-doc
description: Invoke BEFORE writing phpDoc. Provides Nette conventions for docblocks: when to skip documentation, class/method/property/exception docs, generic array types (array, list), conditional return types. Use this whenever writing or editing any /** */ comment - even when the user just says "document this" without mentioning phpDoc.
Documentation (phpDoc)
Golden Rule
Never duplicate signature information without adding value. If the class name, method name, parameter names, and PHP types already tell the full story, skip the docblock entirely.
Skip documentation when:
- The method is trivial and self-explanatory (getters, setters, simple delegations)
- The docblock would only repeat what the signature already says
- Parameter names are descriptive enough (
$width,$height,$name)
Write documentation when:
- The method has non-obvious behavior (returns null in specific conditions, throws exceptions)
- Array contents need specification (
@return string[]) - Parameters have constraints, formats, or valid ranges not captured by PHP types
- The "why" behind a design choice matters for callers
Writing Style
- Always American English (color, not colour; behavior, not behaviour)
- Be concise and direct - avoid unnecessary words
- Start method descriptions with 3rd person singular present tense verb: Returns, Formats, Checks, Creates, Converts, Sets
- Skip phrases like "Class that...", "Interface for...", "Method that..."
- Don't duplicate method lists or implementation details in class docblocks
- Use active phrasing describing main responsibility
Preferred Phrases
Use consistent phrasing for recurring situations:
| Situation | Phrase |
|---|---|
| Returns a value | "Returns..." |
| Returns null on failure | "Returns X, or null if..." |
| Checks a condition | "Checks whether..." |
| Creates an object | "Creates..." |
| Converts format | "Converts X to Y." |
| Sets a value | "Sets..." |
| Finds/searches | "Finds...", "Searches for..." |
| Removes | "Removes..." |
| Validates | "Validates..." |
| Parses | "Parses..." |
Boolean / predicate methods
Describe the condition the method tests, not when it returns true. The return type already says it is a yes/no answer, so naming the truthy branch ("Returns true for...", "Returns true if...") just restates the signature.
- Write what is being checked: "Checks whether...", "Determines whether...", "Tells whether..."
- Don't enumerate the
truecase ("Returns true when...", "Returns true for..."). - Edge cases worth noting belong in the same sentence as the condition, not as a list of return values.
For example, a validator method is documented as "Checks whether the address is a syntactically valid IPv4 or IPv6 address, including IPv4-mapped IPv6." - the focus is the condition, and the special case rides along in the same clause.
Consistency
Across the whole codebase keep documentation uniform:
- All comments should look like they're from one author
- Same level of detail for similar methods
- Same formulations for similar situations
Property Documentation
Use single-line format for simple @var annotations:
/** @var string[] */
private array $name;
Short comments for non-obvious properties:
/** for back compatibility */
protected Explorer $context;
Parameters and Return Values
- Prefer
?TypeoverType|nullfor nullable types - Only document parameters when adding information beyond PHP types
- Use two-space alignment for readability in multi-param blocks:
/** * @return string primary column sequence name * @param mixed $var description here */
Include parameter docs only when explaining:
- Additional context or constraints
- Limitations or conditions
- Unusual usage patterns
Generic Array Types
Array key types
array<T>=array<int|string, T>- any keys (omitting key type means int|string)array<int, T>- int keys only (not necessarily sequential)array<string, T>- string keys onlylist<T>- sequential int keys starting from 0 (0, 1, 2...)
Input vs output distinction
- @return:
list<T>is accurate if the function always returns sequential keys - @param:
list<T>can be too restrictive - may reject valid inputs with non-sequential keys
When to use list<T> for input
Analyze the implementation:
foreach ($arr as $v)- doesn't use keys →array<T>is sufficient$arr[0],$arr[1]- accesses by index → requireslist<T>
Conditional return types
For return types dependent on parameters:
/**
* @return ($flag is true ? list<array{string, int}> : list<string>)
*/
How to determine the correct type
- Examine the implementation - how is the array used?
- Write a test script that outputs the result structure if needed
- For nested arrays, analyze each nesting level separately
Exception Documentation
- Use a single natural-language sentence describing the problem
- Avoid phrases like "Exception that is thrown when..."
- Use consistent phrases:
- "does not exist" - for missing items
- "failed to" - for operation failures
- "cannot" - for impossible operations
- "is not supported" - for unsupported features
Examples:
- "The file does not exist."
- "Cannot access the requested class property."
- "The value is outside the allowed range."
- "Failed to read from or write to a stream."
Examples
Good Documentation
Clear purpose, adding array contents info:
/**
* Returns list of supported languages.
* @return string[] Array of language codes
*/
public function getSupportedLanguages(): array
Describing unusual behavior:
/**
* Creates new transaction. Returns null if user has exceeded daily limit.
*/
public function createTransaction(float $amount): ?Transaction
When to Skip
// Signature says it all - no docblock needed
protected readonly string $name;
public function getWidth(): int
public function setName(string $name): void
Self-explanatory parameters - document only the method purpose:
/**
* Calculates dimensions of image cutout.
*/
public function calculateCutout(int $left, int $top, int $width, int $height): array