Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax of Closure in PHPDoc

Tags:

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?

like image 764
Rene Koch Avatar asked May 16 '13 14:05

Rene Koch


People also ask

How do you write a closure?

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.

What is the closure in PHP?

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.

What is closure in laravel?

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.

What is closure class?

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.


2 Answers

@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().

like image 95
ashnazg Avatar answered Sep 27 '22 16:09

ashnazg


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:

  1. The function body of __invoke is not required, so leave it blank.
  2. Use "Closure" sufix for class name to clarify it.
like image 20
the liquid metal Avatar answered Sep 27 '22 17:09

the liquid metal