Синтаксис закрытия в PHPDoc

Я не могу найти документацию по типу Closure в PHPDoc. Итак, мой вопрос: как определить параметр параметров, отправленных на закрытие, и его возвращаемое значение?

Пример:

Как мне описать, что «обратный вызов» получит «MyCustomClass», число и строку и вернет «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);
})

Или если это вообще возможно?


person Rene Koch    schedule 16.05.2013    source источник
comment
Я не думаю, что есть разумный способ описать это в аннотациях. Даже в руководствах по PHP они просто упоминаются как callable в описаниях аргументов.   -  person Maxim Khan-Magomedov    schedule 16.05.2013
comment
Это то, чего я опасаюсь, но было бы неплохо, если бы это было возможно.   -  person Rene Koch    schedule 16.05.2013
comment
Подробное обсуждение определения закрытия: github.com/phpDocumentor/phpDocumentor2/issues/830   -  person Gerard Roche    schedule 09.09.2016


Ответы (2)


@param callable $callback действительно синтаксис для этой части. Вы не ограничиваете этот параметр тем, что он является самим закрытием... любой вызываемый объект, который передается ему, будет принят в этой реализации. Callable является допустимым «типом PHP», поэтому phpDocumentor принимает его как допустимый тип.

В вашем примере кода на самом деле нет причин предполагать, что ваш метод changer() возвращает MyOtherCustomClass(), поскольку это исключительно продиктовано тем, как вы пишете замыкание позже при использовании changer(). В лучшем случае вы бы указали в комментарии at использование changer(), что это конкретное использование changer() возвращает MyOtherCustomClass, потому что это реализация этого использования, а не сама реализация changer(), который возвращает этот конкретный тип объекта.

Что касается документирования аргументов, которые переданный вызываемый объект должен принимать, я полагаю, вам придется сделать это в части описания тега param. Нет синтаксиса для описания такого случая.

Если бы я реализовал что-то таким образом, я бы наложил интерфейс, который все вызываемые объекты должны явно возвращать, и, таким образом, я мог бы написать, что changer() возвращает этот интерфейс. Конечно, это означает, что ваш MyOtherCustomClass должен реализовать этот интерфейс, но, тем не менее, мне кажется, что это единственный способ приблизиться к "принудительному" типу возвращаемого значения из changer().

person ashnazg    schedule 17.05.2013
comment
Интерфейс мог бы решить проблему, если бы я переписал код. В моем случае это не вариант. - person Rene Koch; 21.05.2013
comment
Действительно, переписывание кода может быть ограничением ;-) Я обнаружил, что размышления о вариантах, которые я исключаю, все же иногда могут привести к появлению других новых идей, поэтому я склонен упоминать такие вещи, которые приходят мне в голову, когда я обдумываю чей-то вопрос. - person ashnazg; 22.05.2013
comment
ставлю вам галочку ... хотя это непригодно для моего текущего проекта, это решение проблемы в целом :) - person Rene Koch; 24.06.2013

используйте непрямой метод

Ваш код:

/**
 * @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);
})

а затем предоставить фиктивный код где-нибудь:

/**
 * this is awesome closure!
 */
class MyFancyClosure {
    /**
     * @param MyCustomClass $cls
     * @param int           $int
     * @param string        $str
     *
     * @return MyOtherCustomClass
     */
    public function __invoke($cls, $int, $str) {}
}

примечание:

  1. Тело функции __invoke не требуется, поэтому оставьте его пустым.
  2. Используйте суфикс «Closure» для имени класса, чтобы уточнить его.
person the liquid metal    schedule 06.07.2018