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

У меня есть класс, который наследуется от суперкласса и где суперкласс имеет статический метод find() который создает экземпляры подкласса (активный шаблон записи).

 class ActiveRecordClass { /** * @return mixed */ public static function find() { // Code returns instance of called class } } class ModelClass extends ActiveRecordClass { } // returns instance of ModelClass, but PHPStorm doesn't realise ModelClass::find($model_id); 

На данный момент док-блок не очень хорош для завершения кода и намека типа. Я не могу использовать суперкласс в качестве возвращаемого типа, поскольку подклассы имеют разные методы из-за столбцов БД.

Как я могу указать PHPStorm, что метод superclass find() возвращает экземпляр подкласса, из которого он вызван, так что завершение кода работает?

Найдено:

 class ActiveRecordClass { /** * @return static */ public static function find() { // Code returns instance of called class } } 

Кажется, что @return self vs @return static работает так же, как вы ожидали бы, учитывая то, что обычно делают ключевые слова. @return self не подобрал методы, доступные на конкретном подклассе, но @return static make autocomplete отлично работает.

 /** * @var ModelClass **/ $model = ModelClass::find($model_id); 

например: установить тип переменной с помощью phpDoc

Также http://phpdoc.org/docs/latest/references/phpdoc/types.html говорят, что вы можете использовать «я» как тип возвращаемого значения

13, элемент, к которому применяется этот тип, относится к одному и тому же классу или к любому из его дочерних элементов, из которого первоначально был задокументирован элемент.

Например:

Метод C () содержится в классе A. DocBlock утверждает, что его возвращаемое значение имеет тип self. Поскольку такой метод C () возвращает экземпляр класса A. Это может привести к запутывающим ситуациям, когда задействовано наследование.

Например (предыдущая примерная ситуация по-прежнему применяется):

Класс B расширяет класс A и не переопределяет метод C (). Таким образом, можно вызвать метод C () из класса B. В этой ситуации может возникнуть неоднозначность, поскольку само может быть интерпретирована как класс A или B. В этих случаях self ДОЛЖЕН быть интерпретирован как экземпляр класса, где DocBlock содержащий тип self, или любой из его дочерних классов.

В приведенных выше примерах self ДОЛЖЕН всегда ссылаться на класс A или B, поскольку он определен с помощью метода C () в классе A.

Если метод C () должен быть переопределен в классе B, включая определение типа в DocBlock, то self будет относиться к классу B или к любому из его детей.

поэтому постарайтесь

 /** * @return self */ public static function find() { // Code returns instance of called class }