I cant find any documentation on the Closure type in PHPDoc. So my question is how do I define the parameter of the parameters sent to the closure and its return value ?
Example:
How do i describe that the "callback" will get a "MyCustomClass", a Number and a String, and return a "MyOtherCustomClass" ?
/**
* @param MyCustomClass $cls
* @param Closure $callback this isn't really explaining what this is
*
* @return MyOtherCustomClass
*/
function changer($cls, $callback){
return $callback($cls, 2, "a string");
}
changer($aCustomeClass, function($cls, $int, $string){
return new MyOtherCustomClass($cls, $int, $string);
})
Or if its at all possible?
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write @escaping before the parameter's type to indicate that the closure is allowed to escape.
Basically a closure in PHP is a function that can be created without a specified name - an anonymous function. Here's a closure function created as the second parameter of array_walk() . By specifying the $v parameter as a reference one can modify each value in the original array through the closure function.
Closures are anonymous functions that don't belong to any class or object. Closures don't have specified names and can also access variables outside of scope without using any global variables.
The Closure class ¶Class used to represent anonymous functions. Anonymous functions yield objects of this type. This class has methods that allow further control of the anonymous function after it has been created. Besides the methods listed here, this class also has an __invoke method.
@param callable $callback
is indeed the syntax to use for that part. You are not limiting that parameter to being a closure itself... any callable that is passed to it will be accepted in that implementation. Callable is a legal "PHP type", so phpDocumentor accepts it as a valid Type.
In your example code, there's actually not a reason to presume that your changer()
method returns a MyOtherCustomClass()
, since that is purely dictated by how you write the closure later in the changer()
usage. At best, you'd denote in a comment at the changer()
usage that this particular use of changer()
returns MyOtherCustomClass
, because it is that usage's implementation, not the changer()
implementation itself, that returns that specific type of object.
As for documenting the arguments that the passed callable is "required" to accept, I suppose you'd have to do that in the description piece of the param tag. There is no syntax to describe such a case.
If I were to implement something in this manner, I would impose an interface that the callables must all explicitly return, and thus I could write that changer()
returns that interface. Of course, this means that your MyOtherCustomClass
must implement that interface, but still, that seems to me to be the only way of coming close to "enforcing" a return type from changer()
.
use indirect technique
Your code:
/**
* @param MyCustomClass $cls
* @param MyFancyClosure $callback
*
* @return MyOtherCustomClass
*/
function changer($cls, $callback){
return $callback($cls, 2, "a string");
}
changer($aCustomeClass, function($cls, $int, $string){
return new MyOtherCustomClass($cls, $int, $string);
})
and than provide a dummy code somewhere:
/**
* this is awesome closure!
*/
class MyFancyClosure {
/**
* @param MyCustomClass $cls
* @param int $int
* @param string $str
*
* @return MyOtherCustomClass
*/
public function __invoke($cls, $int, $str) {}
}
note:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With