A classe ArrayIterator

(PHP 5, PHP 7, PHP 8)

Introdução

Este iterator permite remover e modificar valores e chaves quando iterando arrays e objetos.

Quando você quiser iterar o mesmo array múltiplas vezes você precisa instanciar ArrayObject e criar instâncias de ArrayIterator que é consultado usando foreach ou chamando o método getIterator() diretamente.

Sinopse da classe

class ArrayIterator implements ArrayAccess, SeekableIterator, Countable, Serializable {
/* Constantes */
const integer STD_PROP_LIST = 1;
const integer ARRAY_AS_PROPS = 2;
/* Métodos */
public append(mixed $value): void
public asort(int $flags = SORT_REGULAR): true
public count(): int
public current(): mixed
public getArrayCopy(): array
public getFlags(): void
public ksort(int $flags = SORT_REGULAR): true
public natcasesort(): true
public natsort(): true
next(): void
public offsetExists(mixed $key): bool
public offsetGet(mixed $key): mixed
public offsetSet(mixed $key, mixed $value): void
public offsetUnset(mixed $key): void
rewind(): void
seek(int $position): void
public serialize(): string
public setFlags(string $flags): void
public uasort(callable $callback): true
public uksort(callable $callback): true
public unserialize(string $data): void
valid(): bool
}

Constantes pré-definidas

Flags

ArrayIterator::STD_PROP_LIST

Propriedades do objeto mantém sua funcionalidade normal quando acessadas como lista (var_dump, foreach, etc.).

ArrayIterator::ARRAY_AS_PROPS

Elementos podem ser acessados como propriedades (leitura e escrita).

Índice

add a note

User Contributed Notes 7 notes

up
51
Venelin Vulkov
14 years ago
Another fine Iterator from php . You can use it especially when you have to iterate over objects

<?php
$fruits
= array(
   
"apple" => "yummy",
   
"orange" => "ah ya, nice",
   
"grape" => "wow, I love it!",
   
"plum" => "nah, not me"
);
$obj = new ArrayObject( $fruits );
$it = $obj->getIterator();

// How many items are we iterating over?

echo "Iterating over: " . $obj->count() . " values\n";

// Iterate over the values in the ArrayObject:
while( $it->valid() )
{
    echo
$it->key() . "=" . $it->current() . "\n";
   
$it->next();
}

// The good thing here is that it can be iterated with foreach loop

foreach ($it as $key=>$val)
echo
$key.":".$val."\n";

/* Outputs something like */

Iterating over: 4 values
apple
=yummy
orange
=ah ya, nice
grape
=wow, I love it!
plum=nah, not me

?>

Regards.
up
16
Relakuyae
11 years ago
Need a callback on an iterated value, but don't have PHP 5.4+?  This makes is stupid easy:

<?php
class ArrayCallbackIterator extends ArrayIterator {
  private
$callback;
  public function
__construct($value, $callback) {
   
parent::__construct($value);
   
$this->callback = $callback;
  }

  public function
current() {
   
$value = parent::current();
    return
call_user_func($this->callback, $value);
  }
}
?>

You can use it pretty much exactly as the Array Iterator:

<?php
$iterator1
= new ArrayCallbackIterator($valueList, "callback_function");
$iterator2 = new ArrayCallbackIterator($valueList, array($object, "callback_class_method"));
?>
up
1
butesa at freenet dot de
7 months ago
The documentation states "This iterator allows to unset and modify values and keys while iterating over Arrays and Objects". But if you pass an array to the constructor, the iterator works with a copy of that array, so the modifications will not be written back to that initial array. ArrayObject behaves the same way.

If you want an iterator that writes back to the array, you can use this function:

<?php
function &getArrayIterator(array &$a): Iterator {
    foreach (
$a as $k => &$v) {
        yield
$k => $v;
    }
}
?>

Usage:

<?php
$array
= [1 => 'a', 2 => 'b'];

$iterator = getArrayIterator($array);
foreach (
$iterator as &$value) {
   
$value .= 'x';
}

//array(2) {
//  [1]=>
//  string(2) "ax"
//  [2]=>
//  &string(2) "bx"
//}
//object(Generator)#4 (0) {
//}
var_dump($array);
var_dump($iterator);

?>

Comparison with plain array, ArrayIterator and ArrayObject:

<?php
$array1
= [1 => 'a', 2 => 'b'];
$array2 = [1 => 'a', 2 => 'b'];
$array3 = [1 => 'a', 2 => 'b'];

foreach (
$array1 as &$value) {
   
$value .= 'x';
}

$iterator2 = new ArrayIterator($array2);
foreach (
$iterator2 as &$value) {
   
$value .= 'x';
}

$iterator3 = new ArrayObject($array3);
foreach (
$iterator3 as &$value) {
   
$value .= 'x';
}

//array(2) {
//  [1]=>
//  string(2) "ax"
//  [2]=>
//  string(2) "bx"
//}
var_dump($array1);

//array(2) {
//  [1]=>
//  string(1) "a"
//  [2]=>
//  string(1) "b"
//}
//object(ArrayIterator)#1 (1) {
//  ["storage":"ArrayIterator":private]=>
//  array(2) {
//    [1]=>
//    string(2) "ax"
//    [2]=>
//    string(2) "bx"
//  }
//}
var_dump($array2);
var_dump($iterator2);

//array(2) {
//  [1]=>
//  string(1) "a"
//  [2]=>
//  string(1) "b"
//}
//object(ArrayObject)#2 (1) {
//  ["storage":"ArrayObject":private]=>
//  array(2) {
//    [1]=>
//    string(2) "ax"
//    [2]=>
//    string(2) "bx"
//  }
//}
var_dump($array3);
var_dump($iterator3);
?>
up
9
Sean Burlington
14 years ago
and to iterate recursively use the (sparsely documented)  RecursiveArrayIterator

<?php

$fruits
= array(
               
"apple" => "yummy",
               
"orange" => "ah ya, nice",
               
"grape" => "wow, I love it!",
                
"plum" => "nah, not me"
               
);

$veg = array("potato" => "chips", "carrot" => "soup");
$grocery = array($fruits, $veg);
$obj = new ArrayObject( $grocery );

$it = new RecursiveIteratorIterator( new RecursiveArrayIterator($grocery));

foreach (
$it as $key=>$val)
echo
$key.":".$val."\n";

?>

Output
--------
apple:yummy
orange:ah ya, nice
grape:wow, I love it!
plum:nah, not me
potato:chips
carrot:soup
up
1
shaman_master at list dot ru
3 years ago
If you want something like `ArrayCallbackIterator` by Relakuyae https://www.php.net/manual/ru/class.arrayiterator.php#106231 , use function `iterator_apply`.
up
-8
daniel dot rutkoski at gmail dot com
7 years ago
<?php
class PrintArray
{
    private
$code = null;

    function
__construct ($val)
    {
       
$this->code = $val;
       
$this->_print();
    }
   
    private function
arrayIterator($val, $grau)
    {
       
$grau++;
       
$arr = new \ArrayIterator($val);
        while (
$arr->valid())
        {
            if(
is_array($arr->current()))
            {
               
$this->arrayIterator($arr->current(), $grau);
            }
            else
            {
               
$this->code .= str_repeat(" ", (4 * $grau)) . $arr->key() . " : " . $arr->current() . PHP_EOL;
            }
           
$arr->next();
        }
    }
   
    private function
_print()
    {
        if (
is_array($this->code))
        {
           
$arr = new \ArrayIterator($this->code);
           
$this->code = 'array(' . PHP_EOL;
            while (
$arr->valid())
            {
                if(
is_array($arr->current()))
                {
                   
$this->arrayIterator($arr->current(), 0);
                }
                else
                {
                   
$this->code .= $arr->key() . " : " . $arr->current() . "\n";
                }
               
$arr->next();
            }
           
$this->code .= ')';
        }
        return
$this;
    }
   
    public function
getVal ()
    {
        return
$this->code;
    }
}

$arr = array(
    array(
       
'ok' => 1, array(9,7,5,9,'a','b'=>array(1,2)),
       
'error' => 2, array('h','u','o')
    )
    ,
'array'
);
$pArray = new PrintArray($arr);
var_dump($pArray->getVal());
up
-27
foobuilder at gmail dot com
12 years ago
Unsetting all keys of an ArrayItem within foreach will always leave the second key:

<?php
$items
= new ArrayObject(range(0, 9));

while (list(
$k, $v) = each($items)) {
    unset(
$items[$k]);
}

print_r($items);

//  ArrayIterator Object
//  (
//      [storage:ArrayIterator:private] => Array
//          (
//              [1] => 1
//          )
//  )
?>

I'm not sure if this is a bug as unsetting keys within foreach is usually a bad idea to begin with (use while instead), but it's something to be aware of.
To Top