As interfaces Iterator, ArrayAccess e Countable do PHP

Artigo que explica como utilizar as interfaces Iterator, ArrayAccess e Countable do PHP para gerar classes que possuem comportamentos de um array.

Interface é um recurso das linguagens de programação orientadas a objetos que propicia algumas vantagens ao polimorfismo. PHP oferece algumas interfaces que, caso sejam implementadas em uma classe, resultam em comportamentos especiais. Algumas destas interfaces são: Iterator, ArrayAccess e Countable.


A interface Iterator permite que um objeto possa ser percorrido em uma estrutura foreach ou então com a função each, como se fosse um array. Através da implementação dos métodos exigidos, o objeto informa qual índice/elemento serão devolvidos a cada iteração. Alguns exemplos de classes que implementam esta interface são: classes iteradores da SPL e classes da SPL. Algumas, no entanto, possuem este comportamento nativamente, por serem built-in (implementadas para a linguagem PHP e não com a linguagem PHP), por exemplo a classe SimpleXMLElement.


A interface Countable permite que um objeto seja passado como parâmetro para a função count e que esta função devolva o valor adequado. Por exemplo, uma classe que representa uma coleção de dados.

Por exemplo:

$exemplo = new Colecao();
echo count($exemplo);
echo $exemplo->count();

Note que a segunda e terceira linha fazem a mesma coisa. O benefício desta interface é a possibilidade de trocar algum ponto do código que usava array poder usar uma classe. Assim, os trechos onde era usada a função count para contar o número de elementos, continuam funciondo.


Por fim, a interface ArrayAccess permite que um objeto possa utilizar o operador colchetes para devolver alguma informação, como se fosse um array. Por exemplo:

$exemplo = new Colecao();
$exemplo[0] = 'teste';
echo $exemplo[0];

Embora $exemplo seja um objeto, você pode acessar/verificar/salvar posições definidas entre colchetes. Além de poder acessar atributos e métodos públicos através do operador seta ("->").

2 comentários

Anônimo disse...

Me diz sinceramente, você realmente utiliza isso nos seus projetos?
Por que eu não vi vantagem nenhuma.

Rubens Takiguti Ribeiro (autor do blog) disse...

Olá Anônimo.

Utilizo principalmente a classe Iterator. Se utilizada de forma correta, esta classe pode te dar grandes ganhos de economia de memória. Um caso muito comum é quando se tem um script que consulta algo em banco de dados que retorna muitos resultados. Se você jogar todo resultado em um array e percorrer o array, ele precisa ser alocado na memória (muito consumo). Por outro lado, usando um iterador, você lê um registro por vez (pouco consumo de memória).

Quanto ao ArrayAccess e Countable, como eu disse no artigo, são úteis quando você quer montar uma classe que tenha características parecidas com um array (como acessar uma posição usando colchetes, ou saber a quantidade de itens usando a função count), mas também permite que o objeto tire proveito das características de POO, com métodos, herança, etc.

Em geral, estas classes são muito úteis em camadas mais baixas da aplicação, ou seja, na camada de framework, etc.