rfc:foreach-non-scalar-keys

This is an old revision of the document!


Allow Non-Scalar Keys

  • version 1.0
  • Date: 2013-01-28
  • Author: Levi Morrison levim@php.net
  • Status: Under Discussion

Introduction

Currently if you have a class that implements Iterator in such a way that key returns a non-scalar, you get a warning when using it in a foreach loop. The value of the key is cast to an integer if it is not a scalar.

<?php
 
class MapIterator implements Iterator {
    protected $vals = [];
    protected $keys = [];
    protected $index = 0;
 
    function __construct(array $keys, array $values) {
        $this->keys = $keys;
        $this->vals = $values;
    }
 
    function rewind() {
        $this->index = 0;
    }
 
    function valid() {
        return $this->index < count($this->keys) && $this->index >=0;
    }
 
    function key() {
        return $this->keys[$this->index];
    }
 
    function current() {
        return $this->vals[$this->index];
    }
 
    function next() {
        $this->index++;
    }
 
}
 
$requestA = new StdClass;
$requestA->startLine = 'GET / HTTP/1.1';
$requestA->headers = ['Host' => 'www.php.net'];
 
$responseA = new StdClass;
$responseA->startLine = 'HTTP/1.1 200 OK';
$responseA->headers = [];
 
$requestB = new StdClass;
$requestB->startLine = 'GET /login HTTP/1.1';
$requestB->headers = ['Host' => 'www.php.net'];
 
$responseB = new StdClass;
$responseB->startLine = 'HTTP/1.1 302 Found';
$responseB->headers = ['Location' => 'http://www.php.net/account/login'];
 
$requests = [$requestA, $requestB];
$responses = [$responseA, $responseB];
 
$mapIterator = new MapIterator(
    $requests,
    $responses
);
 
foreach ($mapIterator as $request => $response) {
    var_dump($request);
    var_dump($response);
}

Yields a warning Warning: Illegal type returned from MapIterator::key() in ... and var_dump($request); returns int(0).

Proposal and Patch

I propose that we lift the restriction that forces a scalar value. Instead we simply assign the key variable to whatever was returned from the iterator. The warning will also be removed. This also opens the possibility to use arrays as keys returned from an iterator, and as such I feel we should also add support for `list` in the keys.

There is no patch at this time. I know Ekneuss was working on something but hasn't had time to finish. I also don't know how closely his patch matches up with this proposal, either.

Changelog

version 1.0:

  • proposed
rfc/foreach-non-scalar-keys.1359438851.txt.gz · Last modified: 2017/09/22 13:28 (external edit)