PHPDocumentor basics
January 3, 2011 Leave a Comment
PHPDocumentor is the most advanced automatic documentation system written for PHP, in PHP. This package has many features:
- ability to parse any PHP file, regardless of documentation format
- conforms loosely to the JavaDOC protocol, and will be familiar to Java programmers
- is designed specifically for PHP, and so documents all constants, functions, classes, methods, and class variables
- *NEW 0.4.1* complete phpdoc.de DocBlock tag support. Additions include @var, @magic, @deprec, @todo, and phpdoc.de parsing of @param.
- *NEW 0.4.1* package inheritance in classes
- *NEW* advanced linking creates a hyperlink for every element in the project
- *NEW* page-level documentation, package-level documentation
- *NEW* complete PHPDocumentor spec with extreme detail
- *NEW* option to document @access private elements
- *NEW* indexing by package and overall
- *NEW* Class trees
Note: if this howto looks bad, get a browser that supports css
PHPDocumentor basics
The documentation process begins with the most basic element of PHPDocumentor: a Documentation block or DocBlock. A basic DocBlock looks like this:
/**
*
*/
A DocBlock is an extended C++-style PHP comment that begins with “/**” and has an “*” at the beginning of every line. DocBlocks precede the element they are documenting. To document function “foo()”, type:
/**
* Defies imagination, extends boundaries and saves the world ...all before breakfast!
*/
function foo()
{
}
define() statements, functions, classes, class methods, and class vars can all be documented.
A DocBlock contains three basic segments in this order:
- Short Description
- Long Description
- Tags
The Short Description is on the first line, and can be terminated with a period or with a blank line. The Long Description continues for as many lines as desired and may contain html markup for display formatting. Here is a sample DocBlock with a Short and a Long Description:
/**
* return the date of Easter
*
* Using the formula from "Formulas that are way too complicated for anyone to
* ever understand except for me" by Irwin Nerdy, this function calculates the
* date of Easter given a date in the Ancient Mayan Calendar, if you can also
* guess the birthday of the author.
*/
Tags
Tags are single words prefixed by a “@” symbol. Tags inform PHPDocumentor how to present information and modify display of documentation. All tags are optional, but if you use a tag, they do have specific requirements to parse properly.
A sample DocBlock showing all possible tags
More tags may be added in the future, not all tags are implemented at this time in phpdocumentor, however they are all recognized as tags and will at least be displayed
/**
* The short description
*
* As many lines of extendend description as you want {@link element} links to an element
* {@link http://www.example.com Example hyperlink inline link} links to a website
* Below this goes the tags to further describe element you are documenting
*
* @param type $varname description
* @return type description
* @access public or private
* @author author name
* @copyright name date
* @version version
* @see name of another element that can be documented, produces a link to it in the documentation
* @link a url
* @since a version or a date
* @deprecated description
* @deprec alias for deprecated
* @magic phpdoc.de compatibility
* @todo phpdoc.de compatibility
* @exception Javadoc-compatible, use as needed
* @throws Javadoc-compatible, use as needed
* @var type a data type for a class variable
* @package package name
* @subpackage sub package name, groupings inside of a project
*/
Tag Information:
- @var [type]
type is the type of a class variable. Default is “mixed” if not included. Use this tag to document variables with type restrictions.
- @return [type] [description]
type is the type of a value returned from a method or function.
description a brief description of the value returned - @param [type] [$varname] [description]
/** * return the day of the week * * @param string $month 3-letter Month abbreviation * @param integer $day day of the month * @param integer $year year * @return integer 0 = Sunday, value returned is from 0 (Sunday) to 6 (Saturday) */ function day_week($month, $day, $year) { ... }use this tag in a DocBlock preceding a function or method.
type is the type of parameter$varname, which may be one of: (string, array, integer, double, class, mixed)
$varname is the name of the parameter, and must be preceded by the $ punctuator
description a brief description of this parameter, which may be more than one linethe @param tag can refer to more parameters than the function lists, to allow documenting of functions that use func_get_args
- @link [url] takes url which must contain the protocol (@link http://www.example.com, not @link www.example.com) and outputs a hyperlink
- @author author name prints author’s name, and parses the email address to display a hyperlink. Multiple authors may be listed on one line, but is not recommended
- @access [public/private]. elements are public by default. Using “@access private” prevents PHPDocumentor from documenting the private element
- @see [element] or @see [element1], [element2]…
element may be the name of any documented element (constant, function, class, class method, class variable). PHPDocumentor recognizes the element type based on the presence of punctuators:
- $element is a class variable in the current class – the class that contains the DocBlock
- element() is either a method in the current class or a function in the current file
- element is either the name of a constant or of a class
To resolve name conflicts resulting from inheritance, use the :: scope operator classname::method() or classname::$variable.
/** * class 1 * * example of {@link http://phpdocu.sourceforge.net Inline linking to a website} * example of use of the :: scope operator * @see subclass::method() */ class main_class { /** * example of linking to same class, outputs "function main_class::parent_method() * @see function parent_method */ $var foo = 3; /** * subclass inherits this method. * example of a word which is either a constant or class name, in this case a classname * @see subclass * @see subclass::$foo */ function parent_method() { if ($this->foo==9) die; } } /** * this class extends main_class * @see main_class */ subclass extends main_class { /** * bar. * example of same class lookup - see will look through parent hierarchy to find the method in {@link main_class} * the above inline link tag will parse as main_class * @see parent_method() */ var $foo = 9; } - @package is used to group classes and functions into groups. @package is never assumed, and must be specified to include an element in a package
- @subpackage is used to group classes and functions into sub-sections of the main package
Inline Tag Information:
Inline tags are formatted like: {@tag params}, where “tag” is the name of the inline tag and params is parameters for the inline tag. Inline tags display their output in the normal flow of the text, and should be used in descriptive areas of the DocBlock.
- {@link [@see-style element]} or {@link [URL] [optional description of URL]}
- a @see-style element is described above, and may be the name of a class, function, variable, or constant
- any valid URL (uniform resource locator) will be output as this html: <a> tag as <a href=”URL”>optional description of URL<\a>
valid URLS include websites (http://www.example.com), ftp sites (ftp://ftp.example.com), telnet sites (telnet://example.com), etc.
/** * class 1 * * example of {@link http://phpdocu.sourceforge.net} * displays as "example of http://phpdocu.sourceforge.net" */ class main_class { /** * This function sends the user to {@link http://www.sf.net The SourceForge Website} * displays as "This function send the user to The SourceForge Website" */ function goto_sourceforge() { header("Location: http://www.sf.net"); } } /** * this class extends {@link main_class} * displays as "this class extends main_class" */ subclass extends main_class { /** * bar. * this class inherits {@link main_class::goto_sourceforge()} */ var $foo = 9; }
Elements that can be documented
Every major reusable element in PHP can be documented:
- Packages (see below for details)
- Procedural Pages (see below for details)
- Classes
- Class Methods
- Class Variables
- Functions
- Defines (constants)
Packages are collections of elements into a group for documentation and release purposes. They may contain any of the standard PHPDocumentor elements (class, function, class method, class variable, define). A Package-level doc is an html file with the same name as the package that is located in the same directory as one of the physical files that contains a package element. In other words, for package foo that contains class bar in file /php/bar.php, PHPDocumentor will attempt to document “foo.html” by looking for /php/foo.html.
Package-level docs should be in standard html format. The only valid tags in Package-level documentation are inline tags. For this release, that means ONLY {@link} may be used in package-level documentation
Here is some example package-level documentation for package baz that contains classes fooclass and barclass
<html>
<head>
<title>Package baz>/title>
</head>
<body>
This package is essential. using class {@link fooclass} you can instruct your computer to brush your teeth for you. Combining this functionality with the back massage given by {@link barclass}, you may truly retire in comfort. In particular, {@link barclass::footmassage()} is a most exquisite experience.
Please follow this list of links for more help:
<ul>
<li><a href="http://www.microsoft.com/support"><The reinstall Windows hotline>
<li><a href="http://www.php.net"><Heaven>
<li><a href="http://phpdocu.sourceforge.net"><The PHPDocumentor Homepage>
<li><a href="http://www.chiaraquartet.net"><The most beautiful music you've ever heard>
</ul>
</body>
</html>
Procedural Pages are physical files that contain at least one function or constant. They may also contain classes, but every class is documented separately from the physical file that contains it. In other words, if foo.php contains function bar() and class baz, bar will be documented as part of Procedural Page _foo_php, and class baz will be documented as class baz. PHPDocumentor interprets the first DocBlock in a file as a Procedural Page-Level DocBlock, or page-level DocBlock, if and ONLY if it does not precede any elements before the next DocBlock.
/**
* Page-level DocBlock
*
* This procedural page contains many functions that blah blah blah
*/
/**
* function or define DocBlock
*/
function blah()
{
...
}
The following is an example of a NON-page-level DocBlock
/**
* Almost a Page-level DocBlock
*
* This procedural page contains many functions that blah blah blah
*/
define("screwedup",66);
/**
* function or define DocBlock
*/
function blah()
{
...
}
PHPDocumentor will interpret the first DocBlock as belonging to define("screwedup",66), rather than to the page
All other elements are documented by placing the DocBlock before the element. Any valid PHP Code may be placed between a DocBlock and an element as long as it isn’t another element.
/**
* DocBlock will document function blah()
*/
// random comment
$a += strpos(get_another_thingy(66,$ufta));
$ark->build($a);
// etc. etc.
function blah()
{
...
}
A realistic example
The code below is a sample class showing PHPDocumentor in action
PHPDocumentor can parse any valid PHP code, but it is recommended to follow this style for ease of programming for both you and people who will be using your packages
/**
* A sample class
*
* This class is just random php used as a {@link http://phpdocu.sourceforge.net phpdoc} example
*
* @version 1.0
* @author Joshua Eichorn <jeichorn@phpdoc.org>
* @project test
*/
class phptestclass
{
/**
* A sample class variable
* @access private
* @var string
*/
var $sample;
/**
* The class constructor
*
* This sets up the class and does other random stuff
*/
function phptestclass
{
$this->sample = "test";
}
/**
* A test function
*
* This function returns {@link $sample}
*
* @see set(), $sample
* @return string
*/
function test()
{
return $this->sample;
}
/**
* Set the sample var
*
* @param string $var
* @see phptestclass::$sample, phptestclass::test()
*/
function set($var)
{
$this->sample = $var;
}
}