Back-End

3 jul, 2013

Collections em PHP

Publicidade

O que é?

A biblioteca das Collections é uma das coisas mais úteis na maioria das linguagens modernas, mas por alguma razão o PHP ainda não tem essa funcionalidade como algo padrão. Sim, no PHP temos os poderosos arrays, mas eles têm uma API muito dispersa e trabalhosa para usarmos.

Por essa razão, foi criado o componente Collections, uma incrível biblioteca que reúne as melhores práticas adotadas nas coleções do .NET e Java trabalhando em conjunto com o poder dos arrays do PHP.

Vamos brincar um pouco com essa biblioteca e ver o que ela pode fazer.

Instalação

O componente Collections está disponível para instalação através do composer. Então, para começar, crie no seu projeto um arquivo chamado composer.json e adicione as linhas abaixo:

{
    "autoload": {
        "psr-0": {
            "": ""
        }
    },
    "minimum-stability": "dev",
    "require": {
        "easyframework/collections": "2.1.*"
    }
}

Feito isso, podemos rodar nossa instalação; se você já instalou o composer, vá no seu terminal (linha de comando), navegue até a pasta do seu projeto e rode o seguinte comando:

$ composer install

Uso

A classe Collection

A classe Collection representa a classe List no .NET ou ArrayList no Java. Ela é baseada nos simples arrays não associativos do PHP. Vamos aprender como utilizá-la e adicionar alguns elementos a ela:

$collection = new \Easy\Collections\Collection();
$collection->add('John');
$collection->add('Maria');
$collection->add('Anderson');

foreach($collection as $item){
    echo $item;
}

Simples, não? Vamos continuar com nosso exemplo e contar quantos elementos nós temos nessa coleção.

echo $colletion->count();

Ótimo, agora nós sabemos como adicionar elementos e contá-los na coleção, mas isso é muito simples, qualquer array faz essa tarefa. Então vamos melhorar as coisas: que tal nós ordenarmos os elementos da coleção através de alguma regra? Por exemplo, primeiramente eu quero ordená-los pela ordem natural dos números e depois por ordem alfabética. Vejamos:

$collection->sort(); //por padrão a ordenção é pelas chaves

//isso irá ordenar a coleção por ordem alfabética
$colletion->sort(new \Easy\Collections\Comparer\StringComparer());

//aqui você pode criar o seu comparador para ordenar coleções pelo seu critério
$collection->sort(new YourCustomComaparer());

Agora sim, algo útil. Nós podemos por exemplo criar um ordenador para uma coleção de datas, no qual inserimos apenas datas e ordenamos pela mais recente. Bem, nós podemos fazer muito mais coisas, vamos buscar algum elemento agora:

print_r($collection>contains("John")); //retorna true

Certo, agora que nós sabemos diversas coisas sobre a classe collection, acho que estamos prontos para passar para o próximo tipo de coleção chamada Dictionary.

A classe Dictionary

A classe Dictionary se baseia nos arrays associativos do PHP. Vamos criar um dicionário de pessoas, no qual vamos incluir uma chave e um valor. A chave será o número da pessoa, e o valor será o um array com o nome e a idade dela.

$dictionary = new \Easy\Collections\Dictionary();
$dictionary->add('person1', array(
    'name' => 'John',
    'age' => 20
));
$dictionary->add('person2', array(
    'name' => 'Maria',
    'age' => 19
));
$dictionary->add('person3', array(
    'name' => 'Anderson',
    'age' => 25
));

foreach ($dictionary as $key => $item) {
    echo $key . ": " . $item['name'] . "-" . $item['age'];
}

Uma observação: quando uma chave é inserida, ela não pode se repetir, ou seja, você não poderá incluí-la novamente. Caso você queira alterar o valor daquela chave, deverá utilizar o método set(). Aqui está um exemplo de como alterar uma chave:

$dictionary->set('person1', array('John', 30));

Agora veja como podemos pegar esse elemento pela chave:

//retorna array('name' => John, 'age' => 30)
print_r ($dictionary->getItem('person1'));

Todos os métodos da classe Collection estão disponíveis na classe Dictionary, apenas lembre-se de usá-las em seus devidos locais, ou seja, use o dicionário quando precisar trabalhar com algo com chave e valor.

Outras classes

Ainda temos diversas outras classes para trabalharmos na biblioteca, não vou mostrar todas aqui, mas veja algumas das principais:

  • Collection – Uma coleção genérica para elementos
  • Dictionary – Uma coleção genérica para elementos com chave e valor
  • Queue – Representa uma fila e segue o padrão FIFO (First in First out)
  • Stack – Representa uma pilha e segue o padrão LIFO (Last in First out)
  • CollectionBase – Base para todas as coleções; você pode herdá-la para criar suas próprias coleções

Trabalhando com objetos

Deixei o melhor para o final, vamos trabalhar com alguns objetos. Seguindo nosso exemplo anterior, vamos criar uma classe Person. Para isso, crie um arquivo Person.php no seu projeto e não se preocupe com o ‘require’, já que o composer carrega automaticamente essa classe para nós:

<?php

class Person
{

    private $name;
    private $age;

    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getAge()
    {
        return $this->age;
    }

    public function setAge($age)
    {
        $this->age = $age;
    }

}

Agora que temos nossa classe, vamos instanciar uma nova coleção e adicionar 6 pessoas a ela:

$collection = new \Easy\Collections\Collection();

$collection->add(new Person('John', 20));
$collection->add(new Person('Peter', 20));
$collection->add(new Person('Sophie', 21));
$collection->add(new Person('Angela', 29));
$collection->add(new Person('Maria', 19));
$collection->add(new Person('Anderson', 25));

foreach($collection as $item){
    echo $item->getName();
}

Muito simples. A razão pela qual eu quis mostrar isso é por causa da Expression search API, uma API muito parecida com o LINQ para o.NET, que nos permite fazer buscas com a semântica SQL nas coleções. Vejamos um exemplo – nessa mesma coleção, eu gostaria de mostrar apenas as pessoas que têm 20 anos de idade:

$criteria = new \Easy\Collections\Criteria();
$expr = $criteria->expr()->eq("age", 20);
$criteria->where($expr);
$collection = $collection->matching($criteria);

//só irá listar John e Peter
foreach($collection as $item){
    echo $item->getName() . "-" . $item->getAge();
}

Agora, vamos listar todo mundo cujo nome começa com a letra “A”:

$criteria = new \Easy\Collections\Criteria();
$expr = $criteria->expr()->contains("name", "A");
$criteria->where($expr);
$collection = $collection->matching($criteria);

//irá listar apenas Angela e Anderson
foreach($collection as $item){
    echo $item->getName() . "-" . $item->getAge();
}

Veja como é simples realizar consultas mais complexas nas coleções com essa API. Na forma normal, nós teríamos que percorrer a coleção completa e fazer alguns ‘ifs’ e ‘strstr()’ para encontrarmos esse resultado. Temos muitas outras coisas que podemos usar nesse componente, então não deixe de explorá-lo.

Conclusão

Espero que você tenha gostado do nosso tour pela Collections API. Você pode estar se perguntando o porquê de usar essa biblioteca, e a resposta é muito simples…. Simplicidade, organização e padronização. Minha intenção é só mostrar uma ferramenta útil para você ganhar produtividade.

Eu sou o responsável pelo desenvolvimento da biblioteca e ainda temos muito o que melhorar nela, é por isso que peço sua ajuda para construí-la, seja com documentação ou codificando mesmo!!

Link para o repositório no Github: https://github.com/LellysInformatica/collections

Não se esqueça de dar uma olhada na documentação da API.