Posts tagged SPL
SPL ArrayAccess
2Eae! Hoje vou falar sobre uma das interfaces do PHP!
Bom, o assunto de hoje é a ArrayAccess, que apesar de simples, possibilita que uma classe seja manipulada como um array.
A ArrayAccess, obriga que a classe implemente 4 métodos, são eles:
public boolean offsetExists(mixed $offset) public mixed offsetGet (mixed $offset) public void offsetSet(mixed $offset, mixed $value) public void offsetUnset(mixed $offset)
Através desses métodos, você conseguirá acessar a sua classe como se fosse um array, com algumas restrições é claro
Para demonstrar o uso da ArrayAccess, usarei as mesmas classes usadas do post anteriror, só adicionei a classe CarrinhoCompras onde será posteriormente implementada a ArrayAccess.
class Produto
{
private $nome;
private $preco;
public function __construct($nome, $preco)
{
$this->nome = $nome;
$this->preco = $preco;
}
/** GETTERS AND SETTERS **/
}
class Item implements Countable
{
private $produto;
private $quantidade;
public function __construct(Produto $produto, $quantidade)
{
$this->produto = $produto;
$this->quantidade = $quantidade;
}
public function count()
{
return $this->quantidade;
}
}
class CarrinhoCompras
{
private $itens;
private $data;
public function __construct($data)
{
$this->itens = array();
$this->data = $data;
}
}
Nesse exemplo, continuamos com nosso contexto de e-commerce, a classe Item possui um Produto e a quantidade desejada desse produto, e a classe CarrinhoCompras possui todos os Itens que estão sendo vendidos. Bem simples, apenas para demonstração
Agora sim, vamos ao que interessa! O atributo $itens, é um array de Itens, para acessar ele poderíamos criar um método getItens(), ou qualquer outro método que acesse esse atributo, mas aqui vou demonstrar como acessar ele através da ArrayAccess.
A classe CarrinhoCompras deve implementar a interface ArrayAccess, e implementar todos os métodos acima citados, como no exemplo abaixo.
class CarrinhoCompras implements ArrayAccess
{
private $itens;
private $data;
public function __construct($data)
{
$this->itens = array();
$this->data = $data;
}
public function offsetSet($offset, $value)
{
var_dump(__METHOD__);
$this->itens[$offset] = $value;
}
public function offsetExists($offset)
{
var_dump(__METHOD__);
return isset($this->itens[$offset]);
}
public function offsetUnset($offset)
{
var_dump(__METHOD__);
unset($this->itens[$offset]);
}
public function offsetGet($offset)
{
var_dump(__METHOD__);
return isset($this->itens[$offset]) ? $this->itens[$offset] : null;
}
}
No exemplo eu coloquei var_dump(__METHOD__) dentro de cada método para que você possa ver quando cada método é chamado. Agora vamos executar alguns testes para que você possa ver a utilização da ArrayAccess.
$produto = new Produto('Livro PHP', 78.50);
$item = new Item($produto, 5);
$produto1 = new Produto('Livro Java', 88.50);
$item1 = new Item($produto1, 1);
$carrinho = new CarrinhoCompras(new DateTime());
$carrinho[0] = $item;
$carrinho[1] = $item1;
var_dump($carrinho[0]);
Fácil não? Agora a sua classe é acessível como um array! Mas agora vamos as restrições
// Isso não funciona! // Apesar de a classe ser acessível como um array, ela não é um array... // Fazendo isso, você terá como resultado um foreach de todos os atributos public foreach ($carrinho as $c) var_dump($c); // Isso também não! array_push($carrinho, 'teste'); // Isso funciona! // Mas não como de costume... // O indice vazio, no caso de um array, teria o mesmo comportamento // Que array_push(), mas no caso de um objeto // O indice é covertido para NULL $carrinho[] = 'teste';
Você pode continuar chamando os métodos normalmente, ou seja.
// Isso funciona! $carrinho->offsetExists(0);
Abaixo uma breve explicação de cada método.
// Chamado quando usamos isset() ou empty() public boolean offsetExists(mixed $offset) // Chamado quando usamos empty() // NOTA: Só é chamado quando ArrayAccess::offsetExists() retorna true public mixed offsetGet (mixed $offset) // Chamado quando usamos $obj['index'] = 'teste' public void offsetSet(mixed $offset, mixed $value) // Chamado quando usamos unset() // NOTA: Fazendo casting para (unset) não chama esse método public void offsetUnset(mixed $offset)
É isso, espero que tenham gostado!
Não esqueçam de comentar e de ler a documentação, RTFM.
SPL Countable
1Eae pessoal!!!
Hoje venho falar de um assunto muito interessante, SPL.
Pra quem não conhece, a SPL, é uma biblioteca com diversas classe e interfaces para PHP, que vão desde estruturas de dados, implementações de Design patterns, Iterators, Exceptions e funções diversas.
Nesse post, falarei de uma das interfaces, a Countable que é extremamente simples, porém muito útil!
Antes de ir direto ao assunto, usarei o exemplo abaixo para demonstrar o uso da interface dentro de um contexto de e-commerce.
class Produto
{
private $nome;
private $preco;
public function __construct($nome, $preco)
{
$this->nome = $nome;
$this->preco = $preco;
}
/** GETTERS AND SETTERS **/
}
class Item
{
private $produto;
private $quantidade;
public function __construct(Produto $produto, $quantidade)
{
$this->produto = $produto;
$this->quantidade = $quantidade;
}
}
Nesse exemplo, temos a classe Produto e a classe Item, a Item recebe como parâmetro no
construtor uma instância de Produto e a quantidade desejada desse produto.
Agora se você quer saber a quantidade de produtos que um item possui você pode fazer algo assim?
$produto = new Produto('Livro PHP', 78.50);
$item = new Item($produto, 5);
echo count($item);
Até poderia, mas não seria o resultado esperado. O resultado desse count() seria 1. E agora?
É claro que você poderia criar um método getQuantidade(), ou resolver de alguma outra forma, idéias não faltam
Mas com a SPL você pode sim realizar o código acima e obter o resultado esperado!!!
Vamos lá!
Basta que a classe Item implemente a Countable como no exemplo abaixo.
class Item implements Countable
{
private $produto;
private $quantidade;
public function __construct(Produto $produto, $quantidade)
{
$this->produto = $produto;
$this->quantidade = $quantidade;
}
public function count()
{
return $this->quantidade;
}
}
A interface Countable, obriga você implementar um método count(), mas ai você deve estar se perguntando: “Tá mas onde esta a graça nisso?”. Eu respondo, execute novamente o código abaixo.
$produto = new Produto('Livro PHP', 78.50);
$item = new Item($produto, 5);
echo count($item);
Agora sim! O resultado será 5, isso acontece porque sua classe implementou a interface Countable, e agora o PHP sabe que ele pode chamar o método count() da sua classe quando você utilizar a função count() nativa.
É isso, espero que tenham gostado e até a próxima.