Skip to content

Instantly share code, notes, and snippets.

@Antnee
Last active September 3, 2023 23:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Antnee/fb2c41b0e3cf65eadf0c to your computer and use it in GitHub Desktop.
Save Antnee/fb2c41b0e3cf65eadf0c to your computer and use it in GitHub Desktop.
PHP 7 Generator Return Type
<?php
class Item {
private $id;
public function __construct(int $id)
{
$this->id = $id;
}
public function id() : int
{
return $this->id;
}
}
class Collection {
private $items = [];
public function __construct(Item ...$items)
{
$this->items = $items;
}
public function item() : Generator
{
yield from $this->items;
}
}
$items = [];
for ($i=0; $i<10; $i++) {
$items[] = new Item($i);
}
$collection = new Collection(...$items);
$generator = $collection->item();
printf("\nThe Collection::item() method returns a type of %s, as expected\n", get_class($generator));
printf("However, it yields the following:\n\n");
foreach ($generator as $item) {
printf("\tClass: %s. Calling id() method returns %d (%s)\n", get_class($item), $item->id(), gettype($item->id()));
}
printf("\n\nIt doesn't appear to be possible to hint the yielded type\n\n");
@gallna
Copy link

gallna commented Feb 13, 2016

Or better one: https://3v4l.org/YMQer

@Antnee
Copy link
Author

Antnee commented Feb 19, 2016

@gallna - It's not the prettiest or most obvious piece of code I've ever seen, but I like that last solution. It does what I need it to :) It's a shame that it's such a PITA to get it to do what we're trying to do, but it certainly does it here. Nice one!

@rhift
Copy link

rhift commented Feb 12, 2021

hey @gallna - do you have another link for https://3v4l.org/YMQer by chance? That one produces a 500 and I am interested in your solution =) Thank you!

@Antnee
Copy link
Author

Antnee commented Feb 12, 2021

It works for me @rhift

<?php
class Item {
    private $id;
    public function __construct(int $id)
    {
        $this->id = $id;
    }
    public function id() : int
    {
        return $this->id;
    }
}
class Collection extends IteratorIterator
{
    public function __construct(Item ...$items)
    {
        parent::__construct(
            (function() use ($items) {
                yield from $items;
            })()
        );
    }
    public function current() : Item
    {
        return parent::current();
    }
}
$items = [];
for ($i=0; $i<10; $i++) {
    $items[] = new Item($i);
}
$collection = new Collection(...$items);

foreach ($collection as $item) {
    printf("\tClass: %s. Calling id() method returns %d (%s)\n", get_class($item), $item->id(), gettype($item->id()));
}

@rhift
Copy link

rhift commented Feb 12, 2021

oh weird, thanks for pasting it @Antnee!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment