phpDoc[umentation]

Introduction

Commonly there are two different ways to write doc comments:

  1. API Specifications – code level phpDoc format
  2. Programming Guide Documentation – this guide for example

We use phpDocumentor 2 in writing API specifications and use this wiki for the Programming Guide.

java.sun.com said it well…

“What separates API specifications from a programming guide are examples, definitions of common programming terms, certain conceptual overviews (such as metaphors), and descriptions of implementation bugs and workarounds. There is no dispute that these contribute to a developer’s understanding and help a developer write reliable applications more quickly. However, because these do not contain API “assertions”, they are not necessary in an API specification. You can include any or all of this information in documentation comments (and can include custom tags). …Do not include this level of documentation in doc comments, instead include either links to this information (links to a tutorial and list of changes) or include this information in the same documentation download bundle as the API spec.”

How to Write Doc Comments for the Javadoc Tool

I heavily “borrowed” (and referenced) from the JavaDoc, but this document is not a completely plagiarized copy. There are many things that I have rewritten, reformulated and changed to fit within my view of how to create phpDoc comments and their blocks. I encourage reading of the original, but do not take that as “gospel” on how to create phpDocs within this structure or how to comment within your own PHP code. Remember, this document is written for PHP, the original is written for Java.

Writing API Specifications

Ideally, a API Specification comprises all assertions required to understand and implement this library and structure within your application.

File and Class level comments should include links to the various external tutorials and examples. Most will be located on our website.

Writing phpDoc Comments

phpDoc uses comments blocks called “docBlocks”. Each block is used for a different element of a code set and phpDoc tags are used in all or only a few these blocks.

The blocks types listed below with sample code patterns.

  1. File Level Block
  2. Class Level Block
  3. Class Method/Function Level Block
  4. Class Property Level Block
  5. Variable Level Block
  6. Global Variable Level Block
  7. Constants Level Block

Format of a phpDoc Comment

A phpDoc description can be written in plain text or embellished with HTML [v4.1] tags markdown format. A comment block must be at the top of each file, precede each class, each method of a class, every class property and constant declaration.

A comment block is made up of two parts:

  1. Description Block
    • Single sentence summary
    • Complete description [optional]
  2. Block Tags

Description Block

[cc lang=Php”]
/*
* This is a single sentence descriptor.
*
* This is a multi-line description
* that spans several lines.
*/
[/cc]
The first part of the description block is the summary, a single sentence containing a concise but comprehensive description of the API item. This “first sentence” is defined as “any text up and including the first period.” And this does mean “first period,” so be mindful. This short summary is automatically placed in the class/method summary table (and index).

Place a blank line between this summary sentence and a more complete description. This is more for a visual separation, namely: a person reading the code. The phpDoc ignores this blank line between the descriptors.

A full description should outline the features, requirements, expectations and specify any dependencies where necessary of the API item. This description can be written in plain text or embellished with HTML [v4.1] tags markdown format.

If there is more than one paragraph in the phpDoc comment, separate the paragraphs with a blank line.

Tag Block

An @param tag is “required” (by convention) for every parameter, even when the description is obvious. Even if the method/function does not have an argument list.

The @return tag is required for every method, even if the method/function does not return anything.

[cc lang=php”]
*
* @param boolean $_processSections determine whether to process individual sections
*
* @return object $_controller New Controller Object
*
[/cc]

[cc lang=php”]
*
* @param void
*
* @return void
*
[/cc]

These principles expedite automated searches and processing. Also, a little effort to with what may seem like obvious information pays off in extra clarity for other developers.

Tags should be in a particular, somewhat logical order or pattern.

When the same tag appears more than once in a phpDoc block, each group of tags, such as multiple @uses tags, should be separated from other tags by a blank line with a single asterisk, as this example shows.

[cc lang=Php”]
*
* @uses \Bluewater\Config
* @uses \Bluewater\DB\Table_Adapter
*
* @requires \Bluewater\DB
*
[/cc]

  • Multiple @contributor tags should be listed in chronological order, right after the @author tag which defines the creator of the class.
  • Multiple @param tags should be listed in argument-declaration order. This makes it easier to visually match the list to the declaration.
  • Multiple @throws tags (also known as exception) should be listed alphabetically.

As with any good system, it allows for extensions and customization. phpDocumenter is no different.

I have defined a few “custom” tags within this collection. Your copy of phpDocumenter will have to be updated to understand these new tags and process them. Assuming you wish to generate your own copy of the API docs.

See the complete phpDocumentor Tags list for these custom tags.

On Style

The following are useful tips and conventions for writing descriptions in phpDoc comments.

  • Use the HTML [v4.1] tags markdown “code” to style keywords and names within any phpDoc comment.
  • Omit parentheses when describing the general form of methods.
  • Use complete sentences (and grammar!) in the “complete description” section. It’s okay to use (understandable) phrases instead of complete sentences in the initial summary and in any tag that accepts a description.
  • Use 3rd person (descriptive) not 2nd person (prescriptive).
    The description should be in 3rd person declarative rather than 2nd person imperative (look it up!).

    • Returns the label. (preferred)
    • Return the label. (avoid)
  • A method descriptions begin with a verb phrase. A method implements an operation, so it usually starts with a verb phrase:
    • Returns the label of this button. (preferred)
    • This method returns the label of this button. (avoid)
  • Class/interface/field/etc descriptions can omit the subject and simply state the object (Third Grade English).These APIs often describe things rather than actions or behaviors:
    • A button label. (preferred)
    • This field is a button label. (avoid)
  • Use “this” instead of “the” when referring to an [PHP] object created from the current class. For example, the description of the getToolkit method should read as follows:
    • Gets the toolkit for this component. (preferred)
    • Gets the toolkit for the component. (avoid)
  • Be clear when using the term “field”. Be aware that the word “field” has two meanings:
    • static field, which is another term for “class variable”
    • text field, as in the TextField class. Note that this kind of field might be restricted to holding dates, numbers or any text. Alternate names might be “date field” or “number field”, as appropriate.
  • Avoid Latin (Not everyone knows Latin)
    • Use “also known as” instead of ”aka”
    • Use “that is” or “to be specific” instead of ”i.e.”
    • Use “for example” instead of ”e.g.”
    • Use “in other words” or “namely” instead of ”viz.”
  • Add a description beyond the API name.The best API names are “self-documenting”, meaning they tell you basically what the API does. If the phpDoc comment merely repeats the API name in sentence form, it is not providing anything meaningful. The ideal comment goes beyond those words and should always reward you with some bit of information that was not immediately obvious from the API name.

This example below says nothing beyond what you know from reading the method name. The words “set”, “tool”, “tip”, and “text” are simply repeated in a sentence.

[cc lang=”php” line_numbers=”false”]
/**
* Sets the tool tip text.
*
* @param text the text of the tool tip
*/
public function setToolTipText(String text)
{

}
[/cc]

But, the example below more completely defines what a tool tip is, in the larger context of registering and being displayed in response to the cursor.

[cc lang=”php” line_numbers=”false”]
/**
* Registers the text to display in a tool tip. The text
* displays when the cursor lingers over the component.
*
* @param text the string to display. If the text is null,
* the tool tip is turned off for this component.
*/
public function setToolTipText(String text)
{

}
[/cc]

On Re-Use

You should avoid re-writing phpDoc comments. phpDocumenter can ‘inherit’ comments for methods that override or implement other methods. This occurs in three cases:

  • When a method in a class overrides a method in a superclass
  • When a method in an interface overrides a method in a superinterface
  • When a method in a class implements a method in an interface

In the first two cases, if a method m() overrides another method, the phpDocumenter tool will generate a subheading “Overrides” in the documentation for m(), with a link to the method it is overriding.

In the third case, if a method m() in a given class implements a method in an interface, phpDocumenter will generate a subheading “Specified by” in the documentation for m(), with a link to the method it is implementing.

In all three of these cases, if the method m() contains no doc comments or tags, phpDocumenter will also copy the text of the method it is overriding or implementing to the generated documentation for m(). So if the documentation of the overridden or implemented method is sufficient, you do not need to add documentation for m().

If you add any documentation comment or tag to m(), the “Overrides” or “Specified by” subheading and link will still appear, but no text will be copied.

Example

In this example, the block tags are @name, @access, @final, @PHPUnit (custom tag), @param and, @return.

[cc lang=”php”]
/**
* Indicate whether Yacs_DB will automatically create the database.
*

* If the database does not exist and you would like Yacs_DB (via ADOdb)
* to automatically create the database then set the createdatabase
* switch to true.

* See {@link http://phplens.com/lens/adodb/docs-datadict.htm} for more information.
*
* @name setCreateDB
* @access public
* @final
* @PHPUnit Completed
*
* @since 1.0
*
* @param boolean $_create Create DB state
* @return none
*
*/
public final function setCreateDB ( $_create = true )
{
// Set ADObd DEBUG Flag
$this->createdatabase = $_debug;
}
[/cc]

  • The first line contains the begin-comment delimiter (/**).
  • Each line is indented to align with the code below the comment.
  • Notice the inline tag {@link URL}, which converts to an HTML hyperlink pointing to additional documentation. This inline tag can be used anywhere that a comment can be written, such as in the text following block tags.
  • Insert a blank comment line between the description and the list of tags, as shown.
  • The first line that begins with an ”@” character ends the description. There is only one description block per doc comment; you cannot continue the description following block tags.
  • The last line contains the end-comment delimiter (*/). Note: that unlike the begin-comment delimiter, the end-comment contains only a single asterisk.
  • To make comments readable in many code editors please limit phpDoc comment lines to 76 characters.

References

This document (freely) takes (stole) ideas and concepts from the original piece on this topic… How to Write Doc Comments for the Javadoc Tool.