5. Code structural elements
A structural element is defined in
phpDocumentor as part of the imperative source code, such as PHP or JavaScript, or procedural SQL. For example:
- namespace
- class
- interface
- function
- property
- method
If the source code file has one and only one standalone structural element, as may be required by language-specific coding standards, the file DocBlock is to be reused for this element.
Therefore, classes that are declared in dedicated files must have either no DocBlock or exactly one DocBlock, which refers to the class and file at the same time.
DocBlock for a Class:
While declaring classes or functions, if there must be another file with source code included, the inclusion construct must not be before file header and it must not separate the element DocBlock from the element. There are two solutions possible:
- Have the file header DocBlock separately, then inclusion construct, then a DocBlock for the element with duplicated short description.
- Include it after declaring the element (it is possible in PHP and will not cause issues before execution).
DocBlock with Included Script File:
DocBlock with Included Class File:
Classes and interfaces
Classes and interfaces should have a short description with a human-readable description of the class. If the short description adds no additional information beyond what the type name already supplies, the short description must be omitted.
Good:
Handler for PHP errors/warnings/notices that converts them to exceptions. class ErrorHandler { … }
Bad:
Error Handler class ErrorHandler { … }
If possible, add use cases that suggest where developers can or cannot use the class.
Short name form
It is encouraged to use the short form of the name to encourage readability and consistency with the type hint. The only
exception is in the Service/DTO classes due to tooling requirements.
Example of a Method DocBlock:
Class attributes
Class attributes must have a type declaration using @var tag.
Example of Class Attribute:
Functions and methods
In general, a typed method signature must be preferred over PHPDoc annotations whenever possible.
Functions and methods should have:
- A short description that adds meaningful information beyond the method name.
- If the purpose of the method is not obvious, a long description that explains the motivation behind the implementation. The comment must describe why the method is implemented and not how. For example:
- If a workaround or hack is implemented, explain why it is necessary and include any other details necessary to understand the algorithm.
- For non-obvious implementations where the implementation logic is complicated or does not correspond to the Technical Vision or other known best practices, including an explanation in the doc block’s description. An implementation is non-obvious if another developer has questions about it.
- The declaration of all arguments (if any) using the @param tag, unless the argument type is indicated in the method signature.All @param annotations must include the appropriate argument type. If any argument requires a @param annotation, all arguments must be listed (all or none). @param annotations must be in the same order as the method arguments.
- The declaration of the return type using the @return tag must only be added if the method return type signature does not supply all necessary information (see below for more information on return types).
- A declaration of possible exceptions using the @throws tag, if the actual body of function triggers an exception. All occurrences of @throws in a DocBlock must be after @param and @return annotations.
Exceptions to these rules:
- Testing methods in Unit tests may have doc blocks to describe the purpose of the test, such as referencing Github issues.
- Test method annotations may include data providers and other testing annotations.
Things to include
- An explanation of input arguments and return values if it is not obvious from their name and type.This is applicable in the following cases:
- There is more than one possible input/output type.For example: @return Config|null. The DocBlock should explain what situations will return null.Another example: @param FileInterface|null. The DocBlock should explain what happens when the value of the parameter is null.Ideally, implementations such as these should be avoided:
- The input/output type is a simple type and the format is not clear from the name.
- The input/output is an array with a specific structure.
- The intent of the method along with when or where it can be used.
- If an exception is thrown by a method, explain the cause or situation.
- If the input is confusing or complicated, add examples of the method’s usage in client code or examples of the argument.
Things to avoid
- Copying the algorithm. The algorithm must be self-explanatory and understood by reviewing the code and unit tests.
- Information that is out of date or has the potential to become out of date.
Example of a Method DocBlock:
Divergence in @throws tag
In general, use the @throws tag when the code uses throw:
Example of Throwing Exception Explicitly:
In this case, if an exception is thrown in a sub-routine, then @throws must not be used in the parent method.
However, if the only purpose of the referred sub-routine is to throw a specific exception – then @throws must be used in the parent method. For example:
Throwing Exception Implicitly:
@return tag
In general, method return type signatures should be preferred over @return type annotations. If that is not possible due to ambiguous return types or backward compatibility constraints, the @return type annotation must be used. If there is no explicit return statement in a method or function or a return statement without a value, a void return type must be declared in the method signature. For example:
If the method returns itself, the method signature return type must be self. Here is an example:
If for backward compatibility reasons, no return type can be added to the method signature, a @return $this annotation must be used.
Constants
Constants may have a short description. If the short description adds no additional information beyond what the constant name already supplies, the short description must be omitted.
For example, a global constant:
DocBlock templates
A DocBlock template is a DocBlock that starts from /**#@+*/ and ends with /**#@-*/. Templates are no longer supported by PHPDocumentor. Therefore, they MUST NOT be used.
It is encouraged to replace existing DocBlock templates with regular DocBlock comments when the file is being modified.