vyshkant
@vyshkant
developer

Как документировать тип переменной в классе-наследнике в PHP?

Добрый день!

Столкнулся со следующей проблемой.

Есть класс-родитель, например IterableCollection - итератор, который имплементит интерфейс Iterator. В этом классе есть свойство $items, представляющее собой массив каких-то элементов (для класса IterableCollection не имеет значения, что это за элементы).

class IterableCollection implements \Iterator
{
    /**
     * @var mixed[]
     */
    protected $items = [];

    ...
}


Есть класс SomeCollection, который наследует класс IterableCollection. Данный класс является коллекцией объектов класса SomeClass, и в protected-массиве $items лежат элементы класса SomeClass.

Далее я хочу взять какой-то элемент из protected-переменной $items в классе наследнике, но оказывается (ВНЕЗАПНО), что данный элемент отображается phpStorm'ом как mixed.

class SomeCollection extends IterableCollection
{
    public function doSomeWork()
    {
        $this->items[0]->someMethod();
    }
    ...
}


Проблема заключается в том, что когда я вызываю метод someMethod на объекте $this->items[0], то PhpStorm не понимает, что $this->items[0] является объектом класса SomeClass. В этом ничего удивительного нет, потому что это нигде не объявлено.

Вопрос: есть ли способ средствами phpDoc определить, что в классе SomeCollection переменная $items является не mixed[], а SomeClass[]?

Интересует именно способ сделать это средствами phpDoc, а не каким-либо образом переопределяя данное свойство в классе-наследнике.

Спасибо.

UPD.

Если в классе-родителе указать не
/**
     * @var mixed[]
     */
    protected $items = [];
}

а
/**
     * @var array
     */
    protected $items = [];
}


то способ
/**
 * @property SomeClass[] $items
 */
class SomeCollection extends IterableCollection {
    ...
}


действительно работает.

НО.

В таком случае свойство $items считается магическим и публичным, и phpStorm теперь видит его даже вне класса, что есть неправильно.
  • Вопрос задан
  • 1145 просмотров
Решения вопроса 1
vyshkant
@vyshkant Автор вопроса
developer
Очевидно, что при отсутствии в PHP средств обобщённого программирования (генериков) сделать это без костылей (копирование кода, копирование phpDoc'ов, причисление свойства $items к магическим и публичным etc) невозможно.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@mistergonza
PHP6 evangelist
class SomeCollection extends IterableCollection
{
    /**
     * @var SomeClass[] $items
     */
    ...
    public function doSomeWork()
    {
        $this->items[0]->someMethod();
    }
    ...
}

Как-то так
Ответ написан
iiifx
@iiifx
PHP, OOP, SOLID, Yii2, Composer, PHPStorm
Очень внезапно, и правда :)
/**
* @var mixed[]
*/
protected $items = [];


Вот оно:
/**
 * @property SomeClass[] $items
 */
class SomeCollection extends IterableCollection
// ...


Еще вариант:
public function doSomeWork()
{
    /** @var SomeClass[] $items */
    $items =  $this->items;

    $items[0]->someMethod();
}


И еще вариант:
/**
 * @return SomeClass[]
 */
protected function getItems ()
{
    return $this->items;
}
 
public function doSomeWork()
{
    $this->getItems()[0]->someMethod();
}
Ответ написан
ghost404
@ghost404
PHP Developer
еще вариант с повторным определением свойства с корректный phpDoc
class SomeCollection extends IterableCollection
{
    /**
     * @var SomeClass[]
     */
    protected $items = [];

    public function doSomeWork()
    {
        $this->items[0]->someMethod();
    }
    ...
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы