-
-
Save mvriel/3823010 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* @template <T> The type of the individual elements | |
*/ | |
class ArrayCollection implements IteratorAggregate | |
{ | |
private $elements; | |
/** | |
* @param array<T> $elements | |
*/ | |
public function __construct(array $elements) | |
{ | |
$this->elements = $elements; | |
} | |
/** | |
* @return Iterator<T> | |
*/ | |
public function getIterator() | |
{ | |
return new ArrayIterator($this->elements); | |
} | |
} | |
// usage | |
/** @type ArrayCollection<Foo> $col */ | |
$col = new ArrayCollection(); | |
foreach ($col as $elem) { | |
// $elem is instance of Foo here | |
} | |
?> | |
<?php | |
class ArrayCollection implements IteratorAggregate | |
{ | |
private $elements; | |
/** | |
* @param mixed[] $elements | |
*/ | |
public function __construct(array $elements) | |
{ | |
$this->elements = $elements; | |
} | |
/** | |
* @return ArrayIterator | |
*/ | |
public function getIterator() | |
{ | |
return new ArrayIterator($this->elements); | |
} | |
} | |
// usage | |
/** @type ArrayCollection|Foo[] $col */ | |
$col = new ArrayCollection(); | |
foreach ($col as $elem) { | |
// $elem is instance of Foo here | |
} | |
?> |
I see no problem with supporting:
@type array<object> a list of objects, we don't care about the type
@type array<string,object> a map of strings to objects
The @template proposals is not directly related to arrays and more about allowing to write generic classes in userland while still getting the best autocompletion/static analysis that is possible, and btw, you could have more than one @template annotation on your class if your class needs to fill in more holes (like key, and value in a map as in your \SplObjectStorage example).
I wanted to post here that I have not abandoned the discussion but I have been at PHPNW12 the past weekend and am still catching up. A proper response follows somewhere in the upcoming week
Could these ideas be successfully condensed into just this one syntax:
@type (class name or primitive type 'array')<(optional key type, ) (required member type) (description)
I have been thinking quite a bit about this proposal in the past time and to be honest, it is starting to grow on me. Though I am not so sure about the @template
tag since that would only serve a purpose for a Collection object that only intends to be used with a specific set of values (that and I don't think the name @template
is intuitive).
Some concerns that I still have:
- How to deal with generics where the value may be of several types? Use the or operator (|) as has been done so far?
- We should also support multi-dimensional notations
I think we sould keep the or operator for working with several types. But what do you mean by "multi-dimensional notations"?
Coming from a Java perspective, I would love some kind of Generics support in PHP and/or PHPDOC. 👍
Here is a sample that might make more sense regarding Johannes proposal:
Let's have a look at the SplObjectStorage class, that provides a map where keys can be objects. (http://www.php.net/manual/en/class.splobjectstorage.php)
I like Johannes proposal because I find it very powerful.
However, let's admit that 90% of the time, we are dealing with arrays, not ArrayCollection or SplObjectStorage, so we should be sure that the use of the @type annotation with the array is rock solid.
For this matter, one thing we do not capture is the difference between an indexed array and a hashmap. PHP does not make any difference between those 2 constructs, and yet, they are completely different and the documentation should tell the user whether the array is numerically indexed, or is a map.
A proposal would be to use 2 keys. For instance:
Now, this seems to be a bit of an overkill compared to the more simple proposal from Mike...
In an ideal world, we should also be able to write:
/** @type array<Object> An array of Objects (we don't know about the key) */
But that would not suit well with the @template annotation....
So I'm a bit at a loss here... Any idea on how to make this both powerful and simple to use?