Billy ONeal Billy ONeal - 1 month ago 4x
PHP Question

How should I PHPDoc a callback?

I have a method which extracts a modified preorder tree transversal tree from the database, and filters that using a callback function. For example:

* Recursive function for building the Cas_Template_TreeNode.
* @static
* @param array $rows
* @param callback $filter A function to filter the tree by (return a value convertible to false to remove the item from the tree)
* @return array
private static function MakeTreeGivenDbRows($rows, $filter = null)
if ($filter === null)
$filter = function($unused)
return true;
$result = array();
$childrenCount = 0;
for ($idx = 0; $idx < count($rows); $idx += $childrenCount + 1)
$current = $rows[$idx];
$childrenCount = self::ChildrenCountFromRow($current);
if (!$filter($current))
$childrenStartAt = $idx + 1;
$childRows = array_slice($rows, $childrenStartAt, $childrenCount);
$children = self::MakeTreeGivenDbRows($childRows, $filter);
$result[] = new Cas_Template_TreeNode(self::MakeNodeGivenDbRow($current), $children);
if (empty($result))
return null;
return $result;

I'm not sure what the PHPDoc should be for the variable
-- it's a callback, which is what I've indicated, but I'm not sure if that's correct.

Also, any other comments on the quality (or lack thereof) in this code would be appreciated :)


The correct type-hint is callable, which has been available in e.g PhpStorm for a long time, and is part of PSR-5 which is currently under specification.

(I'm surprised nobody else mentioned callable, it's nothing new and has been used everywhere for years - to my knowledge, callback is not and never was a defined PHP pseudo-type)

Note that callable includes not just closures, but also "old school" PHP callbacks, e.g. array($object, 'methodName') or array('ClassName', 'methodName') and even 'function_name'- to maximize the usefulness of your API, you should cover all of those use-cases, which is quite easy, since both call_user_func and call_user_func_array support all four varieties of callables: function-name as string, object/method-name, class/method-name and closure.