| Home / Section index | www.icosaedro.it | ![]() |
PHPLint Support for phpDocumentorLast updated: 2012-02-02
PHPLint provides support for the phpDocumentor's DocBlock comments (www.phpdoc.org). PHPLint parses and gathers the informations found inside a DocBlock and merges these informations with those gathered from the PHP source and the PHPLint meta-code.
From a DocBlock, PHPLint acquires not only textual descriptions, but it acquires also the types of variables, function arguments and returned values.
What is a DocBlock
What can be commented with a DocBlock
Example
Supported line tags
Types
Literal arrays
The @throws line tag
Namespaces and names resolution
Supported inline tags
When PHPLint meta-code is still required
Missing features and differences
References
Constants, variables, functions, classes, class constants, properties
and methods can be preceded by a multi-line comment properly formatted.
The symbol /** marks the beginning of the DocBlock:
/** Two asterisks after the slash mark the beginning of the DocBlock. */
Every line of the DocBlock may begin with an optional asterisk "*", which is ignored and discarded:
/** * The asterisk at the beginning of every line has only an * aesthetical purpose and, if present, is ignored and will * not be rendered in the generated document. */
Every line, apart from the asterisk and the possible surrounding spaces, is the content of the DocBlock. The structure of a DocBlock consists of three sections: the short description, the long description and the line tags, in this order.
/** * The first sentence is the short description. Any text that * follows up to the first line tag is the long description. * The short description should be short, possibly incomplete * but meaningful, usually not longer than one line of text. * @param int $i A line that begins with @ is a line tag. * @return void And this is another line tag. */
The short description starts at the first non-empty line and spans up to the first empty line, the end of the DocBlock or the first period not included inside a word. If the short description so determined results to be more than 3 lines long, only the first line is taken. If the short description is terminated by a period, the period itself is removed.
All the text between the short description and the first line tag or the end of the DocBlock is the long description.
The short description, the long description and the descriptive text allowed in some of the line tags can contain a subset of the HTML entities as listed below:
<b> <i> <code> <br> <kbd> <p> <pre>
<ul> <ol> <li> <samp> <var>
The last two entities are not real HTML entities, but special tags defined by phpDocumentor; these are passed unchanged but are ignored by WEB browsers. Currently PHPLint does not allow upper-case letter, nor it allows spaces inside the tags, so take care to write them exactly as indicated here otherwise they would be rendered literally. Moreover, PHPLint checks for proper usage of these entities, and raises an error on unclosed tags, wrong nesting, badly formed punctuated lists, etc.
The following tag and special sequences are additions of PHPLint and may be incompatible with other documentation systems:
Single Unicode characters can be entered as "
{" in decimal notation, or as "ƫ" in hexadecimal notation. For example, the asterisk is*.Others tag specific of PHPLint:
<sub> <sup> <blockquote> <center>
These tags, and only these, can be used to format the text of the long
description.
Any other entity or special character including < >
& gets rendered literally (i.e. < is converted
to < and so on).
The text enclosed between <pre> and
</pre> is always rendered literally.
The line tags are all the lines with a leading "@" (extra spaces and tabulations between the asterisk and the "@" are ignored). The first line tag found opens the line tags section of the DocBlock.
Packages.
The word package here is intended in the sense of PHPLint packages, that
is simply a file containing PHP code. The name of the package as set with the
@package line tag is simply used by PHPLint to give a title to the
generated document. If missing, the title of the document is the base name of
the file.
The first DocBlock encountered that contains the @package line tag
is assumed to be the comment about the package itself; in other words, this
line tag is mandatory for DocBlocks that comment a package.
Constants.
Are constants all the items defined with the define() statement.
PHP 5.3 also introduces the const statement with the same
syntax of the class constants: also these constants can be documented with
a DocBlock.
Global variables. It is unusual, but there are cases in which having global variables may be useful. Only global variables can have a DocBlock; local variables cannot.
Functions. DocBlocks for functions may declare the complete signature of the function, including all the formal arguments and the return value. Exceptions inherited are also automatically reported.
Interfaces, abstract classes and concrete classes can have their own DocBlock.
Class constants, properties and methods can have their own DocBlock.
The other elements of the source that cannot be documented:
the namespace statement,
the use statement,
the declare statement,
the include, include_once, require statements.
The following source illustrates the main features of a DocBlock.
<?php
/**
* PhpDoc test source.
*
* This is a <i>package description</i>. This source does
* nothing useful, it is intended only to illustrate the features of the
* phpDocumentor and how a DocBlock looks like.
*
* @package PhpDocTest
* @author Umberto Salsi <phplint@icosaedro.it>
* @version 1.0
* @deprecated Do not use this package, it is completely unuseful!
*/
/*. require_module 'standard'; .*/
/**
* Popular approximation of the greek pi.
*/
define("POPULAR_PI", 3.14);
/**
* Last error code found.
*/
$last_error = 0;
/**
* Search a name inside an array of names. The long description starts
* with this second sentence. Both the short description and the long
* description are optionals.
*
* @param string $name Name of the item we are looking for.
* @param string[int] $arr
* List of items. Note that we have indicated both the type of the
* index (int) and the type of the elements (string):
* this is a PHPLint extension that works also for phpDocumentor.
*
* @return int The index of the element found, or -1 if not found.
*/
function searchName($name, $arr)
{
foreach($arr as $k => $v)
if( $v === $name )
return $k;
return -1;
}
?>
Also the PHP 4 classes can be documented: properties and methods can have a visibility attribute, and methods can have also the static and the final attributes:
<?php
/*. require_module 'pgsql'; .*/
/**
* Example of class to access to the PostgreSQL DB.
*
* @author Umberto Salsi <phplint@icosaedro.it>
*/
class DBAccess {
/**
* Name of the current DB
* @var string
* @access public
*/
var $db_name;
/**
* Current connection to the DB
* @var resource
* @access private
*/
var $db_conn;
/**
* Opens the connection with the given DB
* @access public
* @param string $db_name Name of the DB
* @return void
*/
function DBAccess($db_name)
{
$this->db_conn = pg_connect("dbname=$db_name");
if( $this->db_conn === FALSE )
die("connection to $db_name failed");
$this->db_name = $db_name;
}
/* ... */
}
?>
PHP 5 classes already have their own attributes keywords abstract final static private protected public built-in, and these keywords must be used instead of the DocBlock tags. Also PHP 5 class constants can be documented:
abstract class DBLogger
extends GenericDB
implements Logger
{
/**
* Timeout for any operation on the DB (s)
*/
const TIMEOUT = 0.5;
/**
* Commenting a method in PHP 5. Note that the @access
* tag cannot be used since PHP 5 already has its own
* keyword.
* @param string $query
* @return bool
*/
public abstract function testTimeout($query);
/* ... */
}
Abstract classes and interfaces can be commented with DocBlocks as you can expect:
/**
* Documenting an interface class
*/
interface TreeInterface
{
/**
* Constants are always public. No type declaration is
* required, as their value already says all.
*/
const ROOT_NODE_LEVEL = 0;
/**
* Methods are always abstract, public and non-final.
*
* @param mixed $key
* @return void
*/
function addNode($key);
}
The syntax of every line tag is described with the aid of these elements:
WORD is any sequence of characters not including spaces, tabulations an new-lines. WORDs are rendered literally.
$VAR is the name of a variable. Note that the dollar sign is required.
TEXT is any text, possibly spanning on several lines up to the next line tag or the end of the DocBlock. A TEXT is rendered literally.
DESCR is an HTML text, and the subset of tags already listed for the long description are allowed. The DESCR can span several lines up to the next line tag or the end of the DocBlock. A DESCR enclosed between square parenthesis [DESCR] is optional.
The following table summarizes all the available line tags, their syntax, and the context where they are legal:
| Line tag | PHP 4 | PHP 5 |
|---|---|---|
@abstract | class, method | See note 1. |
@access private | constant, global variable, function, class, property, method | constant, global variable, function, class, class constant |
@access protected | property, method | See note 1. |
@access public | property, method | See note 1. |
@author TEXT | (always) | (always) |
@copyright DESCR | (always) | (always) |
@deprecated DESCR | (always) | (always) |
@final | class, method | See note 1. |
@global TYPE $VAR | global variable | global variable |
@license WORD [TEXT] | (always) | (always) |
@link WORD [TEXT] | (always) | (always) |
@package WORD | package | package |
@param TYPE [&] $VAR [DESCR] | function, method | function, method |
@return TYPE [DESCR] | function, method | function, method |
@see WORD | (always) | (always) |
@since DESCR | (always) | (always) |
@static | method | See note 1. |
@throws WORD [DESCR] | function, method | See note 2. |
@todo DESCR | (always) | (always) |
@var TYPE [DESCR] | property | property |
@version TEXT | (always) | (always) |
Note 1. PHP 5 already has the attributes abstract final private
protected public static. These keywords must be used instead of
the corresponding phpDocumentor line tags.
Note 2. The |
The supported TYPEs are described in the next paragraph.
PHPLint raises a notice if a line tags is used in the wrong context,
for example @var in a function description.
PHPLint raises a warning if a DocBlock omits to declare the type of a variable, function, argument, property or method and this type cannot be guessed from the code.
All the basic PHP types are supported, with the addition of void.
The general syntax in EBNF format is:
TYPE = type_name {index} | array;
type_name = "void" | "bool" | "boolean" | "FALSE" | "false"
| "int" | "integer" | "float" | "double" | "string"
| "resource" | "mixed" | "object" | CLASS_NAME;
array = "array" [ index {index} [type_name] ];
index = "[int]" | "[string]" | "[]";
The following table summarizes the allowed types and their meaning:
| Type | Description |
|---|---|
| void | Functions and methods that do not return a value are declared to return a value of this dummy type. |
| bool or boolean | A boolean value, either FALSE or TRUE. 0 and 1 are numbers in PHPLint and cannot be used in place of the boolean values. |
| int or integer | An integer number. |
| float or double | A floating point number. |
| string | A string of bytes. Variables of this type can also evaluate to NULL under PHPLint. |
| array[K]E | Array with keys of type K and elements of type E. Variables of this type can also evaluate to NULL under PHPLint. |
| resource | Typically an opened file, or a network socket. Variables of this type can also evaluate to NULL under PHPLint. |
| object | Generic object. Variables of this type can also evaluate to NULL under PHPLint. |
| CLASS_NAME | An object of the specified class. Variables of this type can also evaluate to NULL under PHPLint. |
| mixed | A variable of this type is a generic container of any type of value. Variables of this type can also evaluate to NULL under PHPLint. You should avoid mixed variables, or use them with care, because there is very little you can do with variables of such type under PHPLint. |
An array can be described including the type of the index and the type of the elements according to the general form
array[K]EorE[K]
being K the type of the key (int or string) and E
the type of the elements (all the elements must be of the same type). This is
an extension of the array type already supported by phpDocumentor.
Some examples:
| Several ways to define an array type | ||
|---|---|---|
| Long form | Short form | Description |
array |
mixed[] |
index can be both integers and strings, elements mixed (avoid) |
array[] |
mixed[] |
index can be both integers and strings, elements mixed (avoid) |
array[int]string |
string[int] |
array of strings with int index |
array[int][int]float |
float[int][int] |
matrix of floating-point numbers |
array[string]it\icosaedro\bignumbers\Bigint |
it\icosaedro\bignumbers\Bigint[string] |
associative array of big integer numbers |
array[]SomeClass |
SomeClass[] |
array of objects of the class SomeClass, the keys can be both integer numbers and strings (avoid) |
array[int]SomeClass |
SomeClass[int] |
array of objects of the class SomeClass, the keys are integer numbers |
Some functions and methods can return values of different types that
can be listed separated by a vertical bar. Many functions of the
standard library can return some result or FALSE on error.
For example fopen() can return either a resource
or the FALSE value. This practice is discouraged by PHPLint,
but it is tolerated; in this case PHPLint keeps only the first type, then
the remaining types are parsed but ignored. Example:
/**
* Opens my data file
*
* @return resource|FALSE
*/
function my_fopen()
{
return fopen("data.txt", "r");
}
Note that PHPLint allows to indicate the value FALSE in place
of the correct type boolean just to support this common practice.
The Tutorial expands this topic with
several practical examples.
Please, in new software you write (or at least, if it is intended to be
validated by PHPLint) try to choose among the alternatives indicated there.
In PHP, literal arrays can be defined through the array()
constructor. PHPLint parses accurately the literal arrays in order to
guess their type (both index and elements). The manual of PHPLint
explains in detail how these guesses are made. Basically, if no
keys are specified, the type of the index default to int.
The type of the elements is the type of the expression giving
the value of the elements.
For example:
| Literal array | Guessed type |
|---|---|
array() |
mixed[] |
array( array( ) ) |
mixed[int][] |
array( "a" => array( ) ) |
mixed[string][] |
array("AA", "BB") |
string[int] |
array(0=>"AA", 1=>"BB") |
string[int] |
array("a"=>"AA", "b"=>"BB") |
string[string] |
array( new SOME_CLASS() ) |
SOME_CLASS[int] |
array("a"=>array(1.0,0.0), "b"=>array(0.0,1.0)) |
float[string][int] |
/*. (float[int]) .*/ array() |
float[int] |
array( /*. (float[int]) .*/ array() ) |
float[int][int] |
Note that PHPLint encounters a difficulty when the literal array is empty,
because no keys nor elements are available and the resulting type is
an array of unspecified structure (PHPLint will display that as unknown[unknown]).
Such undefined type is likely to produce an error if
it is assigned to some variable or passed by value to a function.
PHPLint allows to add a formal typecast in fromt to the empty array. The
formal typecast /*.(T).*/ tells to PHPLint which is the expected
structure of the empty array.
The same holds when the NULL value is involved in an expression: NULL is a
special value that is assignment-compatible with every array, but it cannot
provide to PHPLint any information about the real structure of the array.
In these cases the correct type should be indicated through a formal
typecast, like in these examples:
<?php
/**
* List of names, initially empty.
* Here using PHPLint formal type-cast.
*/
$names = /*. (string[int]) .*/ array();
/**
* List of names, initially NULL.
* Here using phpDocumentor line tag.
* @global string[int] $names2
*/
$names2 = NULL;
/**
* List of names, initially NULL
*
* When a @global or @var line tag is used, the type specified must match
* the type of the expression. In this case, since the exact type of the
* array is provided by this DocBlock, no ambiguities arises an the formal
* type-cast is not required.
*
* @global string[int] $names3
*/
$names3 = NULL;
/**
* Matrix of coefficients, initially empty
*/
$m = /*. (float[int][int]) .*/ array();
/**
* Prints a list of names. This function requires an array of a well
* defined structure.
*
* @param string[int] $a List of names.
* @return void
*/
function print_names($a)
{
echo count($a), " names in list:\n";
for($i=0; $i<count($a); $i++)
echo $a[$i], "\n";
}
print_names( array( "Foo", "Bar" ) );
/*
* Here the type of the actual argument is correctly guessed by PHPLint
* to be string[int], which matches exactly the type of the formal
* argument $a.
*/
print_names( /*. (string[int]) .*/ array() );
/*
* Note the empty list and the formal typecast. Without this formal
* type-cast PHPLint would raise an error because the type of the array
* unknown[unknown] would be incompatible with any passed actual value.
*/
print_names( NULL );
/*
* NULL is assignment-compatible with the type of the formal argument,
* so no format typecast is required. For the record, since count(NULL)
* gives 0, nothing will be printed by the function.
*/
?>
The @throws line tag is an important extension of PHPLint to the
format of the DocBlock, but it is not officially supported by phpDocumentor.
phpDocumentor simply reports this line tag verbatim.
Instead, PHPLint provides full support for PHP 5 exceptions, including
their declaration inside the DocBlock.
The @throws WORD [DESCR] line tag allows to declare an exception
the function or the method may throw, where WORD is the name of the exception
and DESCR describes the conditions that causes this exception to be thrown:
/**
* Return the size of the file. On 32-bit systems, this function
* returns the correct value also for files whose size is up to 4 GB.
*
* @param string $filename Path of the file.
*
* @return float Size of the file (bytes). Being a float, this value
* may be greater than the maximum allowed for int.
*
* @throws ErrorException If an error occurs accessing the file.
*/
function BigFileSize($filename)
{
$size = @filesize($filename);
if( $size === FALSE )
throw new ErrorException($php_errormsg);
if( $size >= 0 )
return (float) $size;
else
return (float) $size + 2.0 * (1.0 + PHP_INT_MAX);
}
interface MyCollection {
/**
* Return the element of the given index in the list.
*
* @param int $index Index of the element.
*
* @return mixed The element.
*
* @throws OutOfBoundException If the $index is out of bound.
*
* @throws ErrorException Implementing methods may also throw this,
* depending on the specific code that will
* implement this method.
*/
function getElement($index);
...
}
All the checked exceptions a function or method may throw must be declared. It is allowed to add also unchecked exceptions, but these exceptions are reported in the generated documentation only if a descriptive text is also provided; if no descriptive text is provided, the declaration of the unchecked exception is parsed but it is otherwise completely ignored.
The programmer may still add more exceptions the are still not thrown, but that might thrown later in some overriding or implementing method. In fact, as explained in more details in the PHPLint manual, the list of thrown checked exceptions is part of the method contract that implementing and overriding methods must comply with. Basically, implementing and overriding methods can only throw the same checked exceptions the original method throws, or even more specialized exceptions derived from these. In other words, implementing and overriding methods cannot throw new, unrelated exceptions.
In the document generated by PHPLint Documentator, thrown exceptions are always
listed in the order from more specialized ones to more general ones (that is,
parent classes) so to suggest to the programmer the proper order of the
catch() branches.
ATTENTION! Namespaces are still not supported by the official phpDocumentor program, so what follows must be considered as an extension specific of PHPLint.
PHP 5.3 introduces the concept of namespaces with which, for example, the
fully qualified name of a class consists of one or more identifiers
separated by a back-slash character, like in this example:
it\icosaedro\bignumbers\BigInt. To be more precise, we will use
the following nomenclature with examples applied to the class above:
The fully qualified name (FQN) of the class is a sequence of identifiers separated by the back-slash character that univocally identify the item; you may think at it as the real, complete name of the class or function:
it\icosaedro\bignumbers\BigIntA qualified name is a sequence of two or more identifiers separated by the back-slash character, that may represent only part of a FQN:
bignumbers\BigIntThe absolute name of the class is its FQN with a leading back-slash appended to it:
\it\icosaedro\bignumbers\BigIntProper name of the class if the last identifier of the FQN:
BigInt
The namespace\ operator can be used as a shortland to reference an
item which is reachable from the current namespace and the name so generated
is considered absolute. For example, if the current namespace is
it\icosaedro then namespace\bignumbers\BigInt is the
absolute name of the intended item.
Incomplete names, that is qualified and bare identifiers, are also allowed but a special resolution algorithm has to be applied in order to recover the actual absolute name of the intended item. PHPLint applies the same resolution algorithm the PHP interpreter applies. The only difference is that PHPLint performs namespace resolution also in PHPLint meta-code and in DocBlocks.
Then the @param line tag, the @return line tag and
the {@link} all can make reference to constants, functions and
classes using fully qualified names, qualified names, and bare identifiers.
Also the namespace\ operator and the use clauses are
interpreted as usual.
There are only two restrictions to names that occurs in a DocBlock:
a \ b (allowed in PHP code)
must always be written as a\b without white spaces.
{@link} inline tag:
if the specified item is fully qualified, then it is resolved only after the
package has been completely parsed, so that, at least in this particular case,
forward references are allowed. Then {@link namespace\x}
or {@link \a\b\c} might be valid fully qualified references
to some item defined later in the package.
The name resolution is performed in the same context of the DocBlock, so using
the same current namespace and the same list of use mappings. The
following example illustrate the issue with two DocBlocks, the first appears
before a namespace, and the second appears after the namespace:
<?php
/**
* DocBlock outside the namespace. The namespace below declared the class
* BigInt and the function One. To refer to the class BigInt we must use a
* fully qualified name, for example {@link \it\icosaedro\bignumbers\BigInt}
* because this DocBlock is still in global namespace.
*
* Unqualified names as {@link BigInt} and qualified names as {@link
* bignumbers\One()} DO NOT WORK and give an error because cannot be resolved
* in the context of this DocBlock, and because the `use' clauses below
* have a scope limited to their namespace.
*
* Now the mandatory @package line tag, as usual, to give a name to this
* package:
* @package it/icosaedro/bignumbers/BigInt
*/
namespace it\icosaedro\bignumbers;
use it\icosaedro\bignumbers;
use it\icosaedro\bignumbers as BN;
class BigInt {
# ...
}
/**
* Quite unuseful function that returns a cached BigInt(0).
*
* @return BigInt
* Unqualified name here works, but also {@link bignumbers\BigInt}
* and {@link BN\BigInt} are allowed.
*
* @throws \Exception Inherited from BigInt for this and that reason.
* Unuseful (but allowed) leading back-slash.
*/
function Zero()
{
static $zero = /*. (BigInt) .*/ NULL;
if( $zero == NULL )
$zero = new BigInt(0);
return $zero;
}
And here is how a possible client package might use the package above:
<?php
require_once __DIR__ . "/../../bignumbers/BigInt.php";
namespace it\icosaedro\stats\Test;
use it\icosaedro\bignumbers\BigInt;
use it\icosaedro\bignumbers as BN;
/**
* This package performs simple statistical calculations using
* big numbers from the {@link BigInt} class.
*
* @package it\icosaedro\stats\Test
*/
/**
* Calculates the arithmetic mean between {@link BigInt} numbers. This link
* can be resolved using the first "use" clause. With the second "use"
* clause we might also write {@link BN\BigInt} but it is mostly useful to
* build short names of non-class items like the {@link BN\Zero()} function.
* Without any "use" clause we would need to write the fully qualified name
* {@link \it\icosaedro\bignumbers\BigInt}.
*
* @param array[]BN\BigInt $a One, two or more numbers.
*
* Illustrates how the second "use" clause can be used to
* resolve the name. A bare array[]BigInt would be sufficient
* because we have imported the class with the first "use".
*
* @return it\icosaedro\bignumbers\BigInt The arithmetic mean.
*
* Here too, a bare BigInt would be sufficient.
*/
function Mean($a)
{
$n = count($a);
$sum = $a[0];
for( $i = 1; $i < $n; $i++ )
$sum = $sum->add($a[$i]);
return $sum->div( new BigInt($n) );
}
Summarizing, fully qualified, qualified and unqualified names of constants,
functions and classes may appear in the {@link} in line tag and in
the @param and @return line tags as class names, and
in all these cases namespace resolution algorithm applies.
All the items parsed by PHPLint are reported in the generated document with their fully qualified names.
Namespaces declarations by themselves are not reported and cannot be documented with a DocBlock.
The sequence of characters {@ has a special meaning as it
is the beginning of an inline tag. The general syntax of an inline tag
is as follows:
{@TAG}
Some inline tags may have one or more arguments separated by one or more spaces, tabulator characters or line feed; the general structure of an inline tag requiring arguments is a follows:
{@TAG ARG1 ARG2 ... ARGn}
Inline tags are allowed in the short description, in the long description, and in the descriptive text of line tags that have a descriptive text. Inline tags are not allowed, that is are passed verbatim, in any other location.
The inline tags PHPLint supports are listed below:
{@}
{@
that would be otherwise forbidden because them are reserved to start
an inline tag.
{@*}
*/
that would be otherwise forbidden in a multi-line comment. It is mostly
useful when a long chunk of code has to be inserted into the text.
{@link ITEM}{@link ITEM text to be displayed}{@link URL}{@link URL text to be displayed}
{@link M_PI}
inserts a reference to the constantM_PI.
{@link $varName}
inserts a reference to the global variable$varName. Note that the$symbol is mandatory. Variables that are local to a function or method and formal arguments of function and method cannot be referenced.
{@link funcName()}
inserts a reference to the functionfuncName(). Note that the parentheses are mandatory as them allows to distinguish between constants and functions. You may also add specific arguments inside the parentheses, but still spaces are not allowed. For example you may write{@link tan(M_PI)}.
{@link SomeClass}
inserts a reference to the class or interfaceSomeClass.
{@link SomeClass::SOME_CONST}
inserts a reference to the class constantSomeClass::SOME_CONST.
{@link SomeClass::$aProperty}
inserts a reference to the propertySomeClass::$aProperty.
{@link SomeClass::aMethod()}
inserts a reference to the methodSomeClass::aMethod(). Between parentheses, you may enter some specific actual argument just like already explained for functions.
In DocBlocks related to a class, the class name itself can be omitted, so bringing to these shorter references:
{@link ::SOME_CONST}
inserts a reference to the class constantSOME_CONSTdefined inside the same class to which the DocBlock belongs.
{@link ::$aProperty}
inserts a reference to the property$aPropertydefined inside the same class to which the DocBlock belongs.
{@link ::aMethod()}
inserts a reference to the methodaMethod()defined inside the same class to which the DocBlock belongs.
The ITEMs that can be referenced are only those that are available in the
current package, including imported standard modules (see
require_module) and imported packages (see
require_once).
Instead, ITEMs that are not accessible from the current package cannot be
referenced directly but, if really needed, a full URL or a relative path can be
provided instead.
Private items cannot be referenced.
The {@link} inline tag also allows to insert links either to local
file or to remote resources. To avoid URLs and file paths be confused with PHP
documented items, URLs must always indicate the protocol used and file paths
must always be indicated as relative to the directory of the current document
file or as absolute path. For example:
{@link ftp://sources.company.com/myproject/package-1.0.zip}
{@link http://www.company.com/}
{@link mailto:bugs@company.com Please, send bug reports here}
{@link ./anotherPackage.htm}
{@link ../otherLib/otherPackage.htm}
{@link /home/Me/projects/myProject/index.htm}
{@link c:/php-lib/index.htm}
{@img URL}
Unsupported inline tags {@example} {@internal} {@inheritdoc}
{@source} {@tutorial} are reported verbatim.
Invalid inline tags are reported verbatim but signaled as errors.
Nested inline tags are not allowed.
phpDocumentor is devoted to the generate the documentation about the source program, but there are some features of PHPLint that cannot be covered effectively with a DocBlock or are missing at all from phpDocumentor. Here is a list of the features not covered by phpDocumentor and that still require PHPLint meta-code:
Required modules.
Every program and every library depends on some module built-in in the PHP
interpreter. The required modules must be listed and imported with the
/*. require_module 'MODULE'; .*/ meta-code statement, typically
located at the very beginning of the file. Example:
/*.
require_module 'standard';
require_module 'session';
require_module 'mysql';
.*/
See the chapter Importing modules of the reference manual for more details.
Class autoloading.
The /*. pragma 'autoload' ... .*/ statement makes aware PHPLint
that the autoloading of classes is enabled through the magic function
__autoload($callname). See the chapter Autoloading classes
of the reference manual for more details.
Prototypes of functions, classes and methods. When forward reference to functions, classes and methods are required, then a prototype must be used. See the chapter Recursive declarations of the reference manual for more details.
Formal arguments that return by reference.
PHPLint support a new variant of formal argument named return by
reference. Formal arguments that return by reference are arguments passed
by reference that can be unassigned at the time of the call and that the static
analysis performed by PHPLint guaranties to be definitely assigned once the
function or method returns. Arguments that return by reference must be marked
with the /*. return .*/ keyword as in this example:
/**
* Example of argument that returns by reference.
* @param string &$a Argument assigned by this function.
* @return void
*/
function f(/*. return .*/ &$a)
{
$a = "xyz";
}
f($x);
echo $x; # here $x is definitely assigned
See the chapter Functions of the reference manual for more details.
Optional arguments in functions and methods.
The /*. args .*/ meta-code keyword must be present in the list of
formal arguments of functions and methods that that accepts an arbitrary number
of optional arguments after the mandatory ones and after the default ones:
/**
* Example of function that accept optional arguments.
* @param int $mandatoryArg This is a mandatory argument.
* @param int $defaultArg This has a default value.
* @return void
*/
function f($mandatoryArg, $defaultArg = 0 /*. , args .*/)
{ ... }
f(1, 2, 3, 4);
Please note the comma inside the meta-code in the example above. See the chapter Functions of the reference manual for more details.
Qualify the type of NULL and empty array().
Formal type-cast are required when the generic NULL value or the
generic empty array() have to be translated to a specific type. We
already saw several examples before. Formal type-cast are also required
to unbox a mixed variable into an object of a specified class.
Fall-through branches and missing default branch in switch().
In the switch() statement two special statements were introduced
to account for unclosed case branches and missing default branch, that is
missing_break and missing_default. Without these
pseudo-code statements PHPLint would complain on unclosed case branches and
missing default branches. See the chapter Control structures of the
reference manual for more details.
Unchecked exception attribute.
The attribute /*. unchecked .*/ marks an exception as
unchecked. See the chapter Exceptions of the reference manual for more
details.
Throws declaration.
All the checked exceptions a function or method may throw must be declared with
the /*. throws Exception1, Exception2 .*/ statement. Also forward
declarations of functions and methods and also abstract methods must list all
the checked exceptions their implementation is planning to throw.
@category
@example
@exception
@filesource
@ignore
@internal
@method
@name
@property
@staticvar
@subpackage
@tutorial
@uses
.
{@example} {@internal} {@inheritdoc} {@source} {@tutorial}
@package line tag (in PHPLint it
is simply a PHP source file).
@param line tag, the name of the parameter is mandatory,
and it must start with the dollar sign "$". So these lines
are not valid:
@param int maxlen (missing $) @param $maxlen (missing type) @param $maxlen int (TYPE/NAME exchanged)
/**#@+*/ /**#@-*/ are scanned but ignored.
@author line tag: text contained between <> is rendered
literally, not as email hyper-link.
include*() and require*() statements cannot be
documented. PHPLint automatically lists packages imported with
required_once().
@global line tag is only partially supported. phpDocumentor
allows to document a global variable defined inside the scope of a function
or a method (or defined inside a file included by these) using a syntax
similar to this one:
function someFunc()
{
/**
* @global int $GLOBALS['myvar']
*/
$GLOBALS['myvar'] = 123;
}
PHPLint requires that global variables be defined in global scope, so the previous code must be rewritten moving the definition of the global variable into the global scope as follows:
/**
* @global int $myvar
*/
$myvar = 0;
function someFunc()
{
$GLOBALS['myvar'] = 123;
}
This can be parsed by PHPLint. If you are not interested into produce the documentation through phpDocumentor, remember that PHPLint is capable to guess the type of the variable from the expression giving its value, so the DocBlock is checked but unuseful for PHPLint and it can also be removed at all, bringing to the even shorter version that follows:
$myvar = 0;
function someFunc()
{
$GLOBALS['myvar'] = 123;
}
@ignore line tag is not supported. You can use the
@access private line tag instead with a similar effect.
| Umberto Salsi | Contact | Site map | Home / Section index |