Подсказка типа динамического возврата PHP

Предположим, у меня есть следующая функция PHP:

/**
 * @param string $className
 * @param array $parameters
 * @return mixed
 */
function getFirstObject($className, $parameters) {
    // This uses a Doctrine DQl builder, but it could easily replaced
    // by something else. The point is, that this function can return
    // instances of many different classes, that do not necessarily
    // have common signatures.
    $builder = createQueryBuilder()
        ->select('obj')
        ->from($className, 'obj');
    addParamClausesToBuilder($builder, $parameters, 'obj');
    $objects = $builder
        ->getQuery()
        ->getResult();
    return empty($objects) ? null : array_pop($objects);
}

По сути, функция всегда возвращает либо экземпляр класса, указанного параметром $className, либо null, если что-то пошло не так. Единственная загвоздка в том, что я не знаю полного списка классов, которые может вернуть эта функция. (во время компиляции)

Можно ли получить подсказку типа для возвращаемого типа функции такого типа?

В Java я бы просто использовал дженерики, чтобы указать тип возвращаемого значения:

static <T> T getOneObject(Class<? extends T> clazz, ParameterStorage parameters) {
    ...
}

Я знаю о подсказке ручного типа, например

/** @var Foo $foo */
$foo = getOneObject('Foo', $params);

но я хотел бы иметь решение, которое не требует этой шаблонной строки.

Чтобы уточнить: я пытаюсь написать оболочку вокруг Doctrine, чтобы я мог легко получить нужные мне объекты модели, инкапсулируя все специфическое использование системы ORM. Я использую PhpStorm.

** отредактированная функция, чтобы отразить мое предполагаемое использование. Изначально я хотел, чтобы он был чистым от любого конкретного варианта использования, чтобы не раздувать вопрос. Также обратите внимание, что фактическая оболочка более сложна, поскольку я также включаю неявные объектные отношения для конкретной модели и соединения и т. Д.


person LostMekkaSoft    schedule 16.08.2016    source источник
comment
В вашем вопросе есть ошибка: that I do not know the full list of classes this function can return против aware of the manual type hinting, если вы этого не сделаете сейчас, во-первых, как вы это сделаете, единственное решение: все классы должны реализовать один и тот же interface, и этот интерфейс затем используется для возврата типа in PHP7 only, например functionA : interfacX (){}   -  person JustOnUnderMillions    schedule 16.08.2016
comment
В php нет многотипных подсказок (пока): stackoverflow.com/questions/36873567/   -  person Marc B    schedule 16.08.2016
comment
Боковое примечание: в php это /** @var Foo $foo */ позволяет php-инструментам, таким как PHPStrom, предоставлять вам правильный список методов/реквизитов возвращаемого класса, если указан тип 1-1.   -  person JustOnUnderMillions    schedule 16.08.2016
comment
@MarcB Я вижу, что голосование против этой функции. С другой стороны, я просто быстро пролистал. Это со стола?   -  person Alex Karshin    schedule 16.08.2016
comment
@Nordenheim: без понятия. на самом деле не обращайте особого внимания на разработку php. бьет меня, почему они не позволили бы это, так как почти все основные функции php в любом случае уже выполняют возвраты двойного типа. некоторый ресурс/значение или false в случае неудачи. даже если они не сделали это как общий возврат любого типа, разрешение конкретного типа или логического значения, по крайней мере, позволило бы коду пользовательского уровня воспроизводить то, на что уже способны основные функции.   -  person Marc B    schedule 16.08.2016
comment
@JustOnUnderMillions Это не ошибка, это фича! :D Функция getObjects(...) может возвращать любой экземпляр классов, которые добавляются и удаляются во время выполнения. Однако, когда я использую функцию, я точно знаю, какой конкретный класс мне нужен, потому что я указал его в аргументах функции. По сути, я должен сказать две вещи: (1) Дайте мне собаку. и (2) Эта вещь, которую я только что получил, — это собака... Номер 2 кажется необходимым в этом случае использования, но это совершенно избыточное утверждение.   -  person LostMekkaSoft    schedule 17.08.2016
comment
Но PHP не JAVA. ;-)) Так что ООП в PHP немного отличается, намного проще, чем в Java :-) Надеюсь, вы найдете способ, и вы не закончите багги-функцией :))   -  person JustOnUnderMillions    schedule 17.08.2016
comment
@MarcB это не совсем то, о чем он просил. типы союзов не решат эту проблему. Речь идет не об определении нескольких возвращаемых типов, а об определении возвращаемого типа как имени класса, заданного в первом аргументе. Основная проблема в том, что в php нет типов — классы передаются в виде строки. Но, по крайней мере, phpdoc может это поддерживать.   -  person iRaS    schedule 14.08.2018


Ответы (1)


Теперь это можно сделать с помощью подключаемого модуля IntelJ (IDEA/phpStorm/webStorm) DynamicReturnTypePlugin: https://github.com/pbyrne84/DynamicReturnTypePlugin

person allanlaal    schedule 08.12.2020