Home/Section index | www.icosaedro.it | ![]() |
Latest updated: 2009-04-25
Introduction
What will be reported
The description
Documenting the package
Documenting constants
Documenting variables
Documenting functions
Documenting classes
Special tags
Specifying items
Handling the project layout
Support for internationalization
Generating the documentation
Examples
PHPLint support a "documentator" facility, a tool that automatically generates the documentation about a PHP source. Basically, the programmer adds some comments, appropriately formatted, and PHPLint merges them with the informations it gathered from the parsing stage. All these informations are formatted and saved in a file in HTML format. PHPLint supports either the phpDocumentor commenting style and its own commenting style. This latter, named "PHPLint Documentor" is described here.
For example, take this source:
<?php /*. DOC Sample package. <@package DoNothing> This package does nothing, it's only an example. Items internal to the package, as <@item HowManyEmptyElems()>, and external to the package, can be referenced. .*/ /*. require_module 'standard'; require_module 'mysql'; .*/ $myData = array("one", "two", ""); /*. DOC No much to say about this array... .*/ /*. int .*/ function HowManyEmptyElems(/*. array .*/ $a) /*. DOC Returns the number of empty elements The array is scanned, element by element. All the elements that result to be <@item empty()> are counted, and the result is returned. <@see count()> <@see array_count_values()> .*/ { if( $a === NULL ) return 0; $n = 0; foreach($a as $v) if( empty($v) ) $n++; return $n; } ?>
The generated output for this package will look similar to this:
DoNothingSample package. PHP version: 5 Required modules:
Required packages: none
This package does nothing, it's only an example. Items internal to the package, as HowManyEmptyElems(), and external to the package, can be referenced. array[int]string $myData
int HowManyEmptyElems(array $a)
|
These items are reported:
PHP 4 lacks the visibility attribute "private", but PHPLint provides a meta-code alternative. See the section about PHP 4 classes in the PHPLint manual for more details.
PHP 5 lacks the visibility attribute "private" for constants, functions, classes and class constants, but PHPLint provides a meta-code alternative. See the section about PHP 5 classes in the PHPLint manual for more details.
For functions and methods also the thrown exceptions are listed. Thrown exceptions are are collected by PHPLint from several sources:
throw
statements the function or method
directly invokes or acquires from functions or methods it calls.
throws
PHPLint meta-code statement.
All the exceptions generated, inherited and declared are collected by PHPLint
and then listed in the generated documentation in the order from more
specialized ones, to less specialized ones; then exceptions are listed just in
the same recommended order them should be handled a chain of
catch()
branches.
These are the items not documented that are listed inside the section "Private items" of the generated document:
/*. private .*/ define("SecretFile", "/home/someone/data");
/*. private .*/ $Mypkg_counter = 0;
/*. private void .*/ function MyPkg_IncCounter(/*. int .*/ $delta) { $GLOBALS['Mypkg_counter'] += $delta; }
/*. private .*/ class MyInternalCLass { ... }
class SomeClass { /*. private int .*/ var $cnt = 0; }
class SomeClass { /*. private array[int]string .*/ function GetUsersList() { ... } }
These items are not reported at all:
class SomeClass { /*. private .*/ const MaxData = 1000; }
At the base of the PHPLint Documentator is the description,
a special formatted multi-line comment. This comment contains a
short description and a long description. After the starting symbol
"/*.
" there must be the word "DOC
" that
marks this comment to be a description (rather than a chunk of PHPLint
meta-code). The short description is the string that continue
from this word up-to the end of the line or the end of the comment. The
long description is all the text remaining from the short description
up-to the end of the comment. For example:
/*. DOC This is the short description This is the long description. This is the long description. This is the long description. .*/
The spaces before the word "DOC" are ignored. After the DOC word,
the linear spaces "
" and "\t
" are
skipped. Another valid form, perfectly equivalent but more readable:
/*. DOC This is the short description This is the long description. This is the long description. This is the long description. .*/
The format of a description is the HTML code. Note that the special
sequences "?>
" and "*/
" cannot be inserted
directly inside a description, since them would confuse either
PHP and PHPLint. These sequences can be inserted respectively as
"?>
" and "*/
".
A "package" in the sense of PHPLint, is simply the file from which the documentation has to be extracted. For example:
/*. DOC General data manipulation and utilities <@package MyPackage> <@version 1.0 revision 2> <@author Umberto Salsi> This package can handle nearly any thing: numbers, strings, books, paintings, songs, humans and animals. Amazing and simple to use. Really! .*/
Note the special sequences of the form <@...>
:
we will describe them below.
Typically the description of the package is placed at the top of the source and before any declaration, but this is not mandatory. If two or more package descriptions are present, their contents are concatenated to the first description.
Since a package is a generic PHP program, it might declare several constants, variables, functions and classes, in any order. Only the variables that are global are reported: variables that are local to the functions are not considered. Items imported from other included packages are not reported.
The description of a constant must follow immediately its definition, and before any other PHP instruction or PHPLint meta-code:
define('PI', 3.14); /*. DOC Popular value of the greek "pee" constant The value is approximated to two decimals, but for some applications it might be required a more accurate value, for example 3.141592. The <code>standard</code> module provides the constant <code>M_PI</code> that is far more accurate. .*/
The description of a global variable must follow immediately its first assignment, and before any other PHP instruction or PHPLint meta-code:
$logged_users = /*. (array[int]string) .*/ array(); /*. DOC List of the logged users, initially empty .*/
In this example we have omitted the long description, since the short description seems to be enough. Note that we don't need to specify the type of the variable, since this information is already available to the parser and it will be reported into the documentation. The initial value assigned to the variable, however, is not gathered by the parser and, if required, it must be specified along the description.
The description of a function must follow the list of the formal arguments, just before the open curly brace:
/*. void .*/ function logIt(/*.resource.*/ $fd, /*.string.*/ $msg /*., args .*/) /*. DOC Write the message to the file Write the message $msg to the opened file $fd, adding a terminating "\n". If $msg is NULL or empty, raises a E_USER_WARNING and the argument is ignored. If $msg is longer than 100 bytes it is shortened to 100 bytes. If more arguments are passed to the function, they are expected to be strings and are treated exactly as $msg. .*/ { ...code here... }
The type of the formal arguments and the type of the returned value are already gathered by PHPLint, so they don't need to be specified again inside the description.
In the paragraphs above we familiarized with the basic principles of the PHPLint Documentator: first the declaration, then the description. Since the declaration alone already carries so much informations, the description may concentrate on the other details, without repeating what PHPLint already knows. Similar concepts applies to the classes as well:
class ChildClass extends ParentClass /*. DOC Implements some beautiful/specialized features Long description of the class here. It might include a survey of all the public and protected items, along with some examples of code and <a href="http://www.xyz.com/">external</a> references for insights. .*/ { const A_CLASS_CONST = 'ssss'; /*. DOC Description of a class constant .*/ protected static /*. mixed .*/ $my_data = NULL; /*. DOC Description of a property .*/ public /*. void .*/ function __construct() /*. DOC Description of the class constructor You might want to provide more information about this special method inside the long description section of the DOC. Note that the description of a method must follow the list of the formal arguments and must precede the open curly brace {. .*/ { } public /*. void .*/ function set(/*. mixed .*/ $value) /*. DOC Sets the internal state of this object Guess what: this method just sets the protected variable <@item ::my_data>. No much to say about this method - it's really simple. <@see ::Get()> .*/ { $this->my_data = $value; } public /*. mixed .*/ function get() /*. DOC Returns the internal state of this object Please, note that if you haven't set before the state of this object, the value returned will be NULL. <@see ::Set()> .*/ { return $this->my_data; } } interface Tree /*. DOC Example of interface class .*/ { /*. void .*/ function left(); /*. DOC Move to the left branch .*/ /*. void .*/ function right(); /*. DOC Move to the right branch .*/ } abstract class File implements Tree /*. DOC Example of abstract class .*/ { public /*. File .*/ $current = NULL; /*. DOC Current node of the file system tree .*/ abstract /*. void .*/ function left(); /*. DOC Move to the left file (whatever this might mean...) .*/ abstract /*. void .*/ function right(); /*. DOC Move to the right file (whatever this might mean...) .*/ public /*. void .*/ function create(/*. string .*/ $name) /*. DOC Create a new file in the current node .*/ { } }
This example is for PHP 5, but the same apply to PHP 4, with the only difference that there are not class constants and the visibility qualifiers and the "final" and "static" attributes are implemented via PHPLint meta-code. Private items are not reported, so that they don't need to be documented.
Maybe you noticed some strange sequences of
characters inside the descriptions having the form
"<@
tag
arg>
".
These special tags are parsed by the documentator. Some of these special
tags are substituted by another string; others provide some informations
to the documentator and are removed from the description.
The "arg" part of the tag is a text of arbitrary length that can
span several lines and must be in the HTML format. At least a space
between the "tag" part and the "arg" part is required to separate the
two elements. The "arg" part may include other special tags, typically
the <@item>
tags.
Here is the list of the available tags:
<@package
canonical_name_of_the_package>
/home/user/myclass.php
the default name will be
myclass
. This special tag lets the programmer to assign a
different name to the package. For example, writing "<@package
MyClass>
" inside the description of the package, the name of
the package reported into the documentation will be "MyClass".
<@version
html_text>
<@copyright
html_text>
<@license
html_text>
<@author
html_text>
<@author>
tags inside a description are combined in a comma-separated list, with the
ordering of the authors preserved, and reported under the label "Author:"
into the description of the item documented.
<@since
html_text>
<@item
item>
<@item ChildClass::set()>
sets a "click-able"
reference to the method set() of the class ChildClass. The format of the
item specifier is described in the next paragraph "Specifying items".
<@see
item>
<@see strlen()> <@see MyClass::strSize()>
<@deprecated
html_text>
- require_module of a deprecated extension moduleTypically, deprecated items are modules, packages, functions, classes, class constants, properties, and methods that should not be used anymore, and the text should explain why. Possible reasons might be: the item is no more supported; it is bugged; there is a better alternative; might be removed in future release of the package; it is still available for compatibility with older applications. Example:
- require_once of a deprecated package
- usage of deprecated constant/ variable/ function/ class
- usage of deprecated class constant/ property/ method
- usage of non-deprecated class constant/ static property/ static method exported by a deprecated class
<@deprecated <@item ::oldMethod()> should not be used anymore because it does not handle the new format of the data (it raises an error). Use <@item ::newMethod()> instead or, even better, the new extended class <@item NewClass> >
PHPLint raises an error if a non-private class (PublicChild
)
tries to extend a private one (PrivateParent
), since the
program can't sets the HTML anchor pointing to this private parent class,
like in this example:
/*. private .*/ class PrivateParent { } class PublicChild extends PrivateParent { }
The special tags <@items>
and <@see>
allows to specify an item exported by any package parsed by PHPLint,
including the standard modules. An item may be a constant, a variable,
a function, a class, e class constant (PHP 5), a property or a method.
Note. Private properties and private methods cannot be referenced inside the descriptions since they does not exit at all for the client packages so do not require to be documented.
Item specifier | Item referred |
---|---|
CONST | A constant. |
$variable | A global variable. Local variables and function parameters cannot be referred. |
Func() | A function. Note that the parentheses are required. You might want to add some text inside the parentheses, for example the values of the arguments. |
Class | A class. |
Class::CONST | A class constant (PHP 5). |
Class::$property | A property. |
Class::method() | A method. Note that the parentheses are required. You might want to add some text inside the parentheses, for example the values of the arguments. |
Commenting a class and the items exported by that class, the class name
may be omitted for brevity when referring to items inside the same class
the current description belongs.
For example, <@item ::$prop>
refers to the
property $prop of the current class.
PHPLint Documentator raises an error if the item specified is misspelled or do not exist in the source just parsed. Items outside the set of sources parsed in the current run may be referenced by a hand-written HTML anchor, for example:
<a href="modules/pcre.html#preg_match()">preg_match()</a>
A project might consist of several files, spread over a variety of directories and sub-directories. The Documentator generates the documentation trying to preserve the original layout of the project, but some fine tuning might still be required. The features described here are intended just to this purpose.
Relative references. Since the source of a package and its documentation might be stored in different locations, or different computers, the Documentator has special provisions to handle the specific layout of your development system.
Internally, PHPLint store the path of every file as absolute paths. Then the Documentator always try to build relative path-files while composing the URLs of the references, so that the documents generated might be moved preserving the hypertextual links. For example, if the document located in the file
/home/MyName/php-src/MyWebApp.html
needs to reference the item
/home/MyName/php-libs/MyLib.html#$aVar
then the Documentator will guess the URL as
../php-libs/MyLib.html#$aVar
References remapping. As said, the Documentator always try to build HTML anchors as relative paths. This process begins first taking the absolute path of the file, then comparing this absolute path with the absolute path of the source currently being parsed. If a leading part of the two paths match, a relative path is made. For example:
Current source: | /home/MyName/libs/utils/formatter.php |
External file to be referenced: | /home/MyName/libs/bignum/bigint.php |
Resulting relative path: | ../../bignum/bigint.php |
Sometimes relative references aren't enough: if the destination of the
generated documentation has a different layout, the documentation cannot
be moved to that final destination without breaking the links. So,
the Documentator provides another even more general mechanism: the
reference remapping. A reference remap is set by the command line option
--doc-ref-remap A B
. This option says that if the absolute
path of a reference begins with the string "A", then that string must be
replaced by "B".
Suppose, for example, that both formatter.html
and the
bigint.html
files generated from the example above have to
be moved into the same destination directory /usr/www/lib/
so breaking the relative path form formatter.html
to ../../bigint.html
. In this case we may re-map
/home/MyName/lib/bignum/
to /home/MyName/lib/
:
will map any reference to items defined insidephplint --php-version 4 --doc \ --doc-ref-remap /home/MyName/lib/bignum/ /home/MyName/lib/ \ formatter.php
Several --doc-ref-remap
options can be provided, and these are
applied in the order to every link until a match is found. If no match is
found, no replacement take place.
Trick. Set a reference remapping to a WEB application, giving the name of the the document as a parameter:
--doc-ref-remap /home/MyName/lib/ \ http://www.mydomain.com/browse.php?lib=
Every reference to your library will be remapped to an URL having the
form http://www.mydomain.com/browse.php?lib=xxxx
.
Trick. Set a reference remapping to a label that is simple to parse later for string substitutions:
--doc-ref-remap /home/MyName/lib/ \ /__THE_DIR__/
Any character between __THE_DIR__
and the following double-quote
"
if the item being referenced.
Order of the transformations. For every reference inside the documentation, the Documentator applies these transformations, in this order:
/home/MyName/php-src/
"
then:
MyAppl.php
becomes
/usr/MyName/php-src/MyAppl.php
.html
" but the option
--doc-extension
" lets to change it. For example:
/usr/MyName/php-src/MyAppl.php
becomes
/usr/MyName/php-src/MyAppl.html
/home/MyName/php-src/
" to
"/var/www/doc/
" has been defined, then:
/usr/MyName/php-src/MyAppl.html
becomes
/var/www/doc/MyAppl.html
Forms
"
declared inside the source file
"/home/MyName/php-src/libs/Forms.php
" through the
special tag "<@item Forms>
", then:
/var/www/doc/libs/Utils.html#Forms
becomes
libs/Utils.html#Forms
Well, no support is currently provided by PHPLint... By default PHPLint raises
a warning message if any ID or literal string contains non-ASCII caracters
(i.e. bytes in the range from \0x80-\0xFF). These warning messages can be
disabled with the option --no-ascii-ext-check
. IDs containing
non-ASCII chars and the text inside DOC blocks are printed verbatim into
the generated HTML document, while literal strings are always encoded as
ASCII strings using proper escaped sequences. For example, a PHP source,
UTF-8 encoded, and containing this declaration
define("aaaà", "aaaà");
get documented as follows:
aaaà = "aaa\xC3\xA0"
That is because PHPLint is unaware of which actually is the encoding of the strings (PHP 6, some day, will allow the programmer to specify which literal strings are actual text, and which binary strings, so that PHPLint will distinguish the two cases, printing the first as human-readable and properly encoded strings, and the latter as escaped sequences.)
Solutions and workarounds. If you are not interested into internationalization
or your PHP sources contains only ASCII characters (but still your program
can be i18n-aware and have support for encoded strings, etc.), simply
left enabled the option --ascii-ext-check
(it is on by default).
Instead, if your source contains non-ASCII characters, you should first
check it is properly encoded (for example UTF-8) then the option
--no-ascii-ext-check
should be given. The generated HTML
documents will have the same encoding of the source, with the only
exception of the literal strings that will be always ASCII.
phplint --doc MyPackage.php
will produce the file MyPackage.html
containing the
declarations and the respective descriptions. The exact format of this
file is currently under development. Some examples are available from
the on-line version of the PHPLint program when the check-box "Generate
document" is enabled. You might want to thy the examples shown in this
chapter to see how the generated document would look like.
Some examples of documentation generated by the PHPLint Documentator:
standard_reflection
- The reflection module (PHP 5).
Umberto Salsi | Contact | Site map | Home/Section index |