php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #49369 Change current(), key(), next(), etc. to check for Iterator
Submitted: 2009-08-26 10:34 UTC Modified: 2020-06-14 16:37 UTC
Votes:29
Avg. Score:3.8 ± 1.1
Reproduced:20 of 20 (100.0%)
Same Version:9 (45.0%)
Same OS:11 (55.0%)
From: admin at ifyouwantblood dot de Assigned:
Status: Suspended Package: Arrays related
PHP Version: * OS: *
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2009-08-26 10:34 UTC] admin at ifyouwantblood dot de
Description:
------------
it would be helpful for chained Iterators, if the default array functions would check if an given object is an instanceof Iterator and react appropriate.

thus key() calling object->key(), current() calling object->current() and so on.

Reproduce code:
---------------
<?php

class iterator_array implements Iterator
{
	protected $aarray;
	
	public function __construct($array)
	{
		$this->aarray=$array;
	}
		
	public function key()
	{
		return key($this->aarray);
	}
		
	public function current()
	{
		return current($this->aarray);
	}
		
	public function valid()
	{
		return (current($this->aarray)!==FALSE);
	}
		
	public function next()
	{
		next($this->aarray);
	}
		
	public function rewind()
	{
		reset($this->aarray);
	}
}

$i=new iterator_array(Array(1,2));
var_dump(current($i));
var_dump(key($i));
next($i);
var_dump($current($i));
var_dump(key($i));

Expected result:
----------------
int(1)
int(0)
int(2)
int(1)


Actual result:
--------------
array(6) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
  [5]=>
  int(6)
}
string(9) "&#65533;*&#65533;aarray"
bool(false)
NULL


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-01 15:47 UTC] jani@php.net
-Summary: make current(),key(),next() etc. check for Iterator +Summary: Change current(), key(), next(), etc. to check for Iterator -Package: Feature/Change Request +Package: Arrays related -Operating System: +Operating System: * -PHP Version: 5.3.0 +PHP Version: *
 [2012-07-01 11:14 UTC] bugs dot php dot net dot nsp at cvogt dot org
As a further note, the current behavior or current() also leaks private fields unlike e.g. http://php.net/manual/en/language.oop5.iterations.php.

class Test{
  private $field = 5;
  public $field3 = 6;
}
$t = new Test;
print current($t);

Expected result:
6

Actual result:
5
 [2012-11-16 04:27 UTC] levim@php.net
I'm not sure this is a php bug.  Iterators should be rewound almost 100% of the 
time before being used, especially when using an array or an object that 
implements Iterator instead of IteratorAggregate.

Maybe the documentation should try to make this better known?
 [2012-11-16 04:33 UTC] levim@php.net
Also, calling `current($i)` gets the current value of the object `$i` which is the 
array; it doesn't call `$i->current`.
 [2012-11-16 04:35 UTC] levim@php.net
Sorry, I misunderstood the bug. Silly me.  Ignore my above comments.
 [2012-12-09 01:48 UTC] levim@php.net
Added bug #63678 as a duplicate.
 [2016-12-09 12:32 UTC] tom at r dot je
Now that in 7.1 we can type hint iterable this would be very useful.

function foo(iterable $i) {
 
   $first = current($i);
   $last = end($i);

}


Because $i is an iterator or an array, we can't differentiate between $i->current() and current($i) we'd need to do:

function foo(iterable $i) {
 
 	if (is_array($i)) {
 		$first = current($i);
 		$last = end($i); 		
 	}
 	else if ($i instanceof Traversable) {
 		$first = $i->current();
 		foreach ($i as $x) {
 			$last = $x;
 		}
 	}
}

It would be a lot simpler if this logic was abstracted into the various functions so they can work with either Traversable or array types.
 [2020-06-14 16:37 UTC] cmb@php.net
-Status: Open +Status: Suspended
 [2020-06-14 16:37 UTC] cmb@php.net
This feature request would require the deprecation of these
functions working on the mangled property table of objects[1], and
eventually removing support for that.

Only after sufficient time has passed after this removal, changing
the functionality could even be considered.  And still,
introducing this feature would require the RFC process[2].  For
the time being, I'm suspending this ticket.

[1] <https://wiki.php.net/rfc/deprecations_php_8_0#key_current_next_prev_reset_on_objects>
[2] <https://wiki.php.net/rfc/howto>
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Thu Jul 09 03:01:28 2020 UTC