So, in PHPDoc one can specify @var
above the member variable declaration to hint at its type. Then an IDE, for ex. PHPEd, will know what type of object it's working with and will be able to provide a code insight for that variable.
<?php
class Test
{
/** @var SomeObj */
private $someObjInstance;
}
?>
This works great until I need to do the same to an array of objects to be able to get a proper hint when I iterate through those objects later on.
So, is there a way to declare a PHPDoc tag to specify that the member variable is an array of SomeObj
s? @var
array is not enough, and @var array(SomeObj)
doesn't seem to be valid, for example.
To specify a variable is an array of objects:
This works in Netbeans 7.2 (I'm using it)
Works also with:
Therefore use of declaration inside the
foreach
is not necessary.PSR-5: PHPDoc proposes a form of Generics-style notation.
Syntax
Values in a Collection MAY even be another array and even another Collection.
Examples
Note: If you are expecting an IDE to do code assist then it's another question about if the IDE supports PHPDoc Generic-style collections notation.
From my answer to this question.
Netbeans hints:
You get code completion on
$users[0]->
and for$this->
for an array of User classes.You also can see the type of the array in a list of class members when you do completion of
$this->...
I prefer to read and write clean code - as outlined in "Clean Code" by Robert C. Martin. When following his credo you should not require the developer (as user of your API) to know the (internal) structure of your array.
The API user may ask: Is that an array with one dimension only? Are the objects spread around on all levels of a multi dimensional array? How many nested loops (foreach, etc.) do i need to access all objects? What type of objects are "stored" in that array?
As you outlined you want to use that array (which contains objects) as a one dimensional array.
As outlined by Nishi you can use:
for that.
But again: be aware - this is not a standard docblock notation. This notation was introduced by some IDE producers.
Okay, okay, as a developer you know that "[]" is tied to an array in PHP. But what do a "something[]" mean in normal PHP context? "[]" means: create new element within "something". The new element could be everything. But what you want to express is: array of objects with the same type and it´s exact type. As you can see, the IDE producer introduces a new context. A new context you had to learn. A new context other PHP developers had to learn (to understand your docblocks). Bad style (!).
Because your array do have one dimension you maybe want to call that "array of objects" a "list". Be aware that "list" has a very special meaning in other programming languages. It would be mutch better to call it "collection" for example.
Remember: you use a programming language that enables you all options of OOP. Use a class instead of an array and make your class traversable like an array. E.g.:
Or if you want to store the internal objects on different levels within an multi dimensional array/object structure:
This solution replaces your array by an object of type "orderCollection", but do not enable code completion within your IDE so far. Okay. Next step:
Implement the methods that are introduced by the interface with docblocks - particular:
Do not forget to use type hinting for:
This solution stops introducing a lot of:
all over your code files (e.g. within loops), as Zahymaka confirmed with her/his answer. Your API user is not forced to introduce that docblocks, to have code completion. To have @return on only one place reduces the redundancy (@var) as mutch as possible. Sprinkle "docBlocks with @var" would make your code worst readable.
Finaly you are done. Looks hard to achive? Looks like taking a sledgehammer to crack a nut? Not realy, since you are familiar with that interfaces and with clean code. Remember: your source code is written once / read many.
If code completion of your IDE do not work with this approach, switch to a better one (e.g. IntelliJ IDEA, PhpStorm, Netbeans) or file a feature request on the issue tracker of your IDE producer.
Thanks to Christian Weiss (from Germany) for being my trainer and for teaching me such a great stuff. PS: Meet me and him on XING.
Use
array[type]
in Zend Studio.In Zend Studio,
array[MyClass]
orarray[int]
or evenarray[array[MyClass]]
work great.I know I'm late to the party, but I've been working on this problem recently. I hope someone sees this because the accepted answer, although correct, is not the best way you can do this. Not in PHPStorm at least, I haven't tested NetBeans though.
The best way involves extending the ArrayIterator class rather than using native array types. This allows you to type hint at a class-level rather than at an instance-level, meaning you only have to PHPDoc once, not throughout your code (which is not only messy and violates DRY, but can also be problematic when it comes to refactoring - PHPStorm has a habit of missing PHPDoc when refactoring)
See code below:
The key here is the PHPDoc
@method MyObj current()
overriding the return type inherited from ArrayIterator (which ismixed
). The inclusion of this PHPDoc means that when we iterate over the class properties usingforeach($this as $myObj)
, we then get code completion when referring to the variable$myObj->...
To me, this is the neatest way to achieve this (at least until PHP introduces Typed Arrays, if they ever do), as we're declaring the iterator type in the iterable class, not on instances of the class scattered throughout the code.
I haven't shown here the complete solution for extending ArrayIterator, so if you use this technique, you may also want to:
offsetGet($index)
andnext()
is_a($object, MyObj::class)
from the constructor into a private methodoffsetSet($index, $newval)
andappend($value)