A
A
Anton Dyshkant2016-03-14 14:50:59
PHP
Anton Dyshkant, 2016-03-14 14:50:59

How to document the type of a variable in a derived class in PHP?

Good afternoon!
Faced the following problem.
There is a parent class, for example IterableCollection - an iterator that implements the Iterator interface. This class has the $items property, which is an array of some elements (for the IterableCollection class, it does not matter what these elements are).

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

    ...
}

There is a SomeCollection class that inherits from the IterableCollection class. This class is a collection of objects of the SomeClass class, and the protected array $items contains the elements of the SomeClass class.
Next, I want to take some element from the $items protected variable in the derived class, but it turns out (SUDDENLY) that this element is rendered by phpStorm as mixed .
class SomeCollection extends IterableCollection
{
    public function doSomeWork()
    {
        $this->items[0]->someMethod();
    }
    ...
}

The problem is that when I call the someMethod method on the $this->items[0] object, PhpStorm doesn't understand that $this->items[0] is an object of the SomeClass class. There is nothing surprising in this, because it is not declared anywhere.
Question: Is there a way using phpDoc to determine that in the SomeCollection class the $items variable is not mixed[] , but SomeClass[] ?
Interested in the way to do this using phpDoc , and not in any way overriding this property in the derived class.
Thank you.
UPD.
If the parent class does not specify
/**
     * @var mixed[]
     */
    protected $items = [];
}

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

then the way
/**
 * @property SomeClass[] $items
 */
class SomeCollection extends IterableCollection {
    ...
}

really works.
BUT.
In this case, the $items property is considered magic and public, and phpStorm now sees it even outside the class, which is wrong.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
Anton Dyshkant, 2016-12-26
@vyshkant

Obviously, in the absence of generic programming tools (generics) in PHP, it is impossible to do this without crutches (copying code, copying phpDocs, assigning the $items property to magic and public ones, etc.).

M
mistergonza, 2016-03-14
@mistergonza

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

Something like this

V
Vitaly Khomenko, 2016-03-14
@iiifx

Very sudden indeed :)

/**
* @var mixed[]
*/
protected $items = [];

Here it is:
/**
 * @property SomeClass[] $items
 */
class SomeCollection extends IterableCollection
// ...

Another option:
public function doSomeWork()
{
    /** @var SomeClass[] $items */
    $items =  $this->items;

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

And another option:
/**
 * @return SomeClass[]
 */
protected function getItems ()
{
    return $this->items;
}
 
public function doSomeWork()
{
    $this->getItems()[0]->someMethod();
}

P
Peter Gribanov, 2016-05-10
@ghost404

another option with re-defining the property with the correct phpDoc

class SomeCollection extends IterableCollection
{
    /**
     * @var SomeClass[]
     */
    protected $items = [];

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question