Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the iterator_to_array function in PHP?

Tags:

php

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?

like image 243
Rajesh Patel Avatar asked Oct 01 '16 10:10

Rajesh Patel


2 Answers

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.

like image 36
HPierce Avatar answered Oct 18 '22 03:10

HPierce


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.

like image 124
Rajdeep Paul Avatar answered Oct 18 '22 03:10

Rajdeep Paul