I'm having a hard time understanding PHP's iterator_to_array
function.
I tried reading the manual but that didn't help.
What is it? How can I use it? What are the appropriate use cases?
Iterators are useful because they allow you to use a custom defined order of data within a foreach
loop. Let's take this (slightly pared down) example from the PHP manual:
class myIterator implements Iterator {
private $position = 0;
private $array = array(
"firstelement",
"secondelement",
"lastelement",
);
public function __construct() {
$this->position = 0;
}
function rewind() {
$this->position = 0;
}
function current() {
return $this->array[$this->position];
}
function key() {
return $this->position;
}
function next() {
++$this->position;
}
function valid() {
return isset($this->array[$this->position]);
}
}
$it = new myIterator;
To iterate over it, we can use a foreach
loop just like an array:
foreach($it as $ele){
echo $ele;
}
Unlike an array, however, you cannot access a single element without iterating to it first. Attempting to do so will give you a fatal error:
/*
* Fatal error: Uncaught Error: Cannot use object of type myIterator as array
* in /home/hpierce/sandbox.php
*/
echo $it[1];
//Iterating to the second element.
$it->next();
// "secondelement"
echo $it->current();
To access a single element, you could use iterator_to_array()
to cast the iterator as an array and then access the element without the extra step:
$array = iterator_to_array($it);
// "secondelement"
echo $array[1];
If you know ahead of time that you will need to access a single element within an iterator, you should consider using ArrayIterator instead.
In a nutshell, iterator_to_array()
function takes an iterator of type Traversable
and convert it to an associative/non-associative array, depending upon the argument provided. From the documentation,
array iterator_to_array ( Traversable $iterator [, bool $use_keys = true ] )
The function takes the following two arguments,
The first argument is of type Traversal
, which is an interface. Both IteratorAggregate
and Iterator
class extends this interface. You can implement these two classes in your custom class, like this:
class myIterator implements IteratorAggregate {
private $array = array('key1'=>'value1', 'value2', 'value3', 'value4');
public function getIterator(){
return new ArrayIterator($this->array);
}
}
$obj = new myIterator;
$array = iterator_to_array($obj->getIterator(), true);
var_dump($array);
Or,
class myIterator implements Iterator {
private $key;
private $array = array('key1'=>'value1', 'value2', 'value3', 'value4');
public function __construct(){
$this->key = key($this->array);
}
public function rewind(){
reset($this->array);
$this->key = key($this->array);
}
public function current(){
return $this->array[$this->key];
}
public function key(){
return $this->key;
}
public function next(){
next($this->array);
$this->key = key($this->array);
}
public function valid(){
return isset($this->array[$this->key]);
}
}
$obj = new myIterator;
$array = iterator_to_array($obj, true);
var_dump($array);
The most important point to note here is that argument 1 passed to iterator_to_array()
function must implement interface Traversable
, so you cannot directly pass an array or object of any other type to this function. See the following example,
$array = array('key1'=>'value1', 'value2', 'value3', 'value4');
$array = iterator_to_array($array, true); // wrong
The second argument is a boolean value, to indicate whether to use the iterator element keys as index or not. See Example #1 here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With