One of the trickier feature requests for phpDocumentor has been
documenting "magic" object properties and methods. By "magic" I am
referring to properties and methods that are created dynamically by PHP
5.0+ userspace class methods __get, __set, __isset, __unset and __call.
For instance, this code creates a read-only property named $foo and a write-only property named $bar and a regular property named $regular as well as a magic function borp() that accepts two parameters.
<?phpclass blah
{ private
$_thingy;
private
$_bar;
function __get
($var) { switch ($var) { case 'foo' :
return 45;
case 'regular' :
return $this->_thingy;
} } function __set
($var,
$val) { switch ($var) { case 'bar' :
$this->_bar =
$val;
break;
case 'regular' :
if (is_string($val)) { $this->_thingy =
$val;
} } } function __call
($method,
$params) { if ($method ==
'borp') { if (count($params) ==
2) { return $params[0] *
$params[1];
} } }}?> In order to document this stuff, we want to add 4 new tags that would only be recognized in a class docblock. They are:
- @property - magic class variables that can be both read and written to
- @property-read - magic class variables that can only be read
- @property-write - magic class variable that can only be written to
- @method - magic class methods
@property and company would have this basic format:
@property type $varname [description]
@method would have this basic format:
@method returntype function_name(type $param1[ = ][, type $param2[ = ]...]) [description]
So, in order to document the previous example code, we would use:
<?php/**
* show off @property, @property-read, @property-write, @method
*
* @property mixed $regular regular read/write property
* @property-read int $foo
* @property-write string $bar
* @method int borp(int $int1, int $int2) multiply two integers
*/class blah
{ private
$_thingy;
private
$_bar;
function __get
($var) { switch ($var) { case 'foo' :
return 45;
case 'regular' :
return $this->_thingy;
} } function __set
($var,
$val) { switch ($var) { case 'bar' :
$this->_bar =
$val;
break;
case 'regular' :
if (is_string($val)) { $this->_thingy =
$val;
} } } function __call
($method,
$params) { if ($method ==
'borp') { if (count($params) ==
2) { return $params[0] *
$params[1];
} } }}?> This example is rather poor usage of __get/__set/__call, but our point is the documentation, so ignore that for now
. We will be accepting feedback for about two weeks, and at that point will announce the decision of how these things will be documented at http://www.phpdoc.org. If you are a developer of an IDE and would like to standardize this decision, or are a user with a real need for this feature, please let us know if there is a better way of doing that that we have not thought of. Comment on this entry or send an email to cellog at the-language-we're-talking-about.net