18

Lets say I have a function (obviously a trivial example):

public function dot(){
    return implode('.', func_get_args());
}

Now I know I could modify this to be

public function dot(array $items){
    return implode('.', $array);
}

but with some functions that is not an option. So, how would you document the first version of the function with a docBlock so an IDE can interpret that it can receive unlimited parameters?

I have seen some methods that use:

/**
 * Joins one or more strings together with a . (dot)
 * @param string $string1
 * @param string $string2
 * @param string $_ [optional]
 * @return string
 */
public function dot($string1, $string2, $_ = null) {
    return implode('.', func_get_args());
}

Which in an IDE looks like autocomplete example

But that feels like a hack to me, is there no way to do it just with docBlock?

Hailwood
  • 79,753
  • 103
  • 257
  • 412
  • This is a great question but took me a while to find. Can I suggest squeezing the word "variadic" into the title to make it easier to find? – Martin Joiner Jul 05 '18 at 11:32

3 Answers3

16

[UPDATED 2015-01-08]

Old way to do this in PHPDoc was:

http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tags.param.pkg.html

/**
 * @param int $param,...
 **/

However, this is no longer supported. As of PHP 5.6 Variadic Method Parameters are a part of the PHP language, and the PHPDoc's have been updated to reflect this as of PHPDoc 2.4 if I recall correctly. This is also in the PhpStorm IDE as of EAP 139.659 (should be in 8.0.2 and up). Not sure about implementation of other IDEs.

https://youtrack.jetbrains.com/issue/WI-20157

In any case, proper syntax for DocBlocks going forward for variadic parameters is:

/**
 * @param int ...$param
 **/
Kevin Nelson
  • 7,156
  • 4
  • 29
  • 39
11

As Variadics are implemented in PHP 5.6 PHPDocumentor should support the following syntax as of version 2.4.

/**
 * @param Type ...$value
 * Note: PHP 5.6+ syntax equal to func_get_args()
 */
public function abc(Type ...$value) {}

This should be the correct way to describe such a signature. This will likely be included in PSR-5. Once that is accepted IDE's should follow to support this "official" recommendation.

However, in the mean time some IDE's have an improved understanding of what they consider correct. Hit hard on the IDE vendor to support the offical PHP syntax that is supported as of 5.6 or use whatever works in the meantime.

Rangad
  • 1,849
  • 20
  • 28
2

In php the concept of valist or list of "optional arguments" does not exist.

the $_ variable will just contain, here the third string you give. The only way to allow an array OR a string is to test the first argument with is_array()

public function dot($arg1){
   if(is_array($arg1)){
       return implode('.',$arg1);
   }
   else if $arg1 instanceof \Traversable){
       return implode('.',iterator_to_array($arg1));
   }
   else{
       return implode('.',func_get_args());
   }
}

Now that you handled the behaviour you want, you have to document it. In php, as overloading is not allowed, a convention is to use "mixed" as a type if you want to provide multiple types.

/**
*@param mixed $arg1 an array, iterator that will be joined OR first string of the list
*@return string a string with all strings of the list joined with a point
*@example dot("1","2","3"); returns 1.2.3 dot(array(1,2,3)); returns 1.2.3
*/

Moreover, according to phpdocumentor documentation you can declare sort of valist with

/**
*@param string ... list of strings
*/
artragis
  • 3,797
  • 1
  • 15
  • 28