Generators, Key/Value Pairs, and the “Space Ship” Operator

In my longer introduction to PHP generators we didn’t talk much about a generator’s “key” values . In other words — when presented with code like this

function someGeneratorFunction() {
    yield 'foo';
    yield 'baz';
    yield 'bar';
}

$generator = someGeneratorFunction();
foreach($generator as $key=>$value) {
    echo $key,"\n";
}

What will the value of $key be? For the above code, the answer is pretty simple — the $key will be an integer that counts up. The first time we ask for a value from the generator ( foo ) the key will be 0 . The second time we ask for a value ( baz ) the value will be 1 , etc.

However— it’s possible to create generators that return meaningful keys. i.e. it’s possible to have a generator that behaves more like what you’d call an associative array, hash map, or dictionary (depending on where you went to school and how old you are). Consider the following sample program.

function generatorWithKeyValuePairs() {
    yield 'foo'=>'bar';
    yield 'baz'=>'bing';
    yield 'boo'=>'woo';
}

$generator = generatorWithKeyValuePairs();

foreach($generator as $key=>$value) {
    echo $key,"=>", $value,"\n";
}

Run this, and you’ll get the following output

foo=>bar
baz=>bing
boo=>woo

If you take a look at the values the generator returns, you’ll see some syntax that’s a little funky.

yield 'foo'=>'bar';

That’s the string foo and the string bar joined by the double arrow operator (some folks call this the spaceship operator). I say this syntax is a little weird, because if you try something like this

var_dump (('foo'=>'bar'));

PHP will yell at you

Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW)

For most working PHP developers, the only time we use the double arrow operator is during array creation

$array = ['foo'=>'bar'];
$array = array('foo'=>'bar');

However, this is also the operator you use when you want to yield both a key and a value. In the following yield , the key returned is foo , the value returned is bar .

yield 'foo'=>'bar';

The first time I saw this syntax it was a little jarring, but after thinking about it, and using it for a bit, it makes sense. The double arrow operator is how we assign keys to a PHP Array, why not also use it when we want a generator to return a key along with a value.

There is one last interesting case to consider — what would a generator’s keys be here?

function generatorWithKeyValuePairs() {
    yield 'foo'=>'bar';
    yield 'baz';
    yield 'boo'=>'woo';
}

With two yields using the double arrow operator, and one using a single value, there’s some ambiguity as to what they key for yield 'baz' should be. Should it be 1 since it’s the second yield , or should it be 0 since it’s the first yield without an explicit key. We’ll leave it as an exercise for the reader to discover which choice PHP made, but (same as in PHP arrays themselves) we’d recommend staying away from this mixed key approach in your own code.