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. 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 most obvious 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. Also, as pointed out elsewhere, the double arrow is also the operator used in PHP’s for each
consrtuct, which also likely influneced the descision to use it for yielding a key/value pair.
foreach($list as $key=>$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.