
It would have certainly happened to you to define a
phpDocumentor annotation on a function or a method:
<?php
/**
* @param string $a name your parameter better than this one
* @return boolean
*/
function doSomething($a)
{
// code...
}These annotations are parsed by phpDocumentor to automatically produce
Api documentation in various formats, such as html and pdf.
It is also true that you can specify a class name as a data type:
<?php
/**
* @return Zend_Form_Element
*/
function doSomething()
{
// code...
}Since this is a widely employed standard for php frameworks, I decided to rely on
@return annotations as the mean to define domain model relationships in my project
NakedPhp. This is not different from the relationships phpDocumentor infers to generate links between html documents: for instance the Zend_Form_Element return type definition would be printed as a link to its actual Api documentation html page, to allow fast navigation.
But what happens when you want to specify that a methods return an array or a collection of elements?
<?php
/**
* @return array
*/
function doSomething()
{
// code...
}Not very clear, as the question that arises is "What is the type of array elements?"
Note that Php is a dynamic language and arrays can be heterogenous, but very often they contain elements of the same type for the sake of consistency; consider for example an array of Zend_Form_Element instances: even if they are different elements they share a common superclass whose methods you can call without fear.
Note also that Php lacks a real collection class or interface, and even if a generic one is provided by a framework, the annotation would not be much clear.
/**
* @return Doctrine\Common\Collections\Collection
*/
or:
/**
* @return ArrayObject
*/
At least in the former case you know that there are homogeneous elements in the returned collection, but the situation is the same.
Since arrays and collections are used as dumb containers, the first thing you will do on an array is to iterate on it, and then you will need to know what is the class of the contained elements to find out which methods to call, or which methods accept this kind of elements.
Of course you can do something like this:
/**
* @return array of @see Zend_Form_Element
*/
But this is not a standard, and different developers would use different annotations:
/**
* @return array this contains Zend_Form_Element instances
*/
/**
* @return array of Zend_Form_Element
*/
These annotations would be parsed by phpDocumentor, but the class name would be mangled in a string and not manageable anymore. It's like scraping a blog versus using a feed.
PHPLint documentation says it recognizes annotations like
array[K]E, as in this example:
/**
* @return array[string]Zend_Form_Element
*/
They also say that phpDocumentor already support it, but there is no trace of that in
its own documentation:
The datatype should be a valid PHP type (int, string, bool, etc), a class name for the type of object returned, or simply "mixed".
The original
Naked Objects implementation is written in Java and takes advantage of
generics (not available in Php):
/**
* @return List<FormElement>
*/
When
javadoc or Naked Objects parse annotations, they know instantly the collection elements type, thanks to a reasonable standard that imitates the language syntax: I would be glad to do the same in Php, but there is no syntax to refer to.
I turn thus to the community, which comprehends millions of talented developers. My question is:
how would you specify @return annotations for containers of elements in a way to include the elements type? I hope to grasp a
de facto standard, which I can then require to follow in NakedPhp applications.