Cuando trabajamos con bases de datos en Laravel hacemos uso del ORM que trae consigo el framework por defecto, se trata de Eloquent, el cual nos ofrece un gran número de métodos muy útiles al momento de interactuar con cada modelo de datos (o tabla dentro de una base de datos). Por ejemplo

// Nueva instancia del modelo user
$user = new User;
// Devuelve el registro con id = 1
$user->find(1);

Para mas información sobre Eloquent visita nuestros tutoriales al respecto.

Esto es gracias a la clase Collection de Eloquent que a su vez extiende de la clase Illuminate\Support\Collection de Laravel. Esta clase nos ofrece también otra forma de trabajar con variables de tipo Array gracias al helper collect() de Laravel.

$array = [1,2,3,4,5];
$collection = collect($array);

// Devuelve "1" -- el primer elemento del array
$collection->first();

Visita el post sobre Uso de colecciones en Laravel.

Desafortunadamente cuando usamos el helper collect() no podemos obtener los valores de un array de la misma forma que lo hacemos con los objetos de Eloquent; Es decir, no podemos llamar $user->name, por el contrario tenemos que usar el método get() para obtener el valor.

$user = ['name' => 'Joe', 'age' => 25];

$user = collect($user);

$user->get('name');

Vamos a solucionar ese problema extendiendo la funcionalidad de la clase Illuminate\Support\Collection en una nueva clase que llamaremos Collector. Primero crearemos un nuevo directorio llamado Collector dentro de la carpeta app/. Una vez hecho esto, vamos a crear un nuevo archivo para nuestra clase llamado Collector.php que extenderá a la clase Illuminate\Support\Collection.

<?php

namespace App\Collector;

use Illuminate\Support\Collection as Collection;

/**
* collector class
*/
class Collector extends Collection
{
    //code here
}

Cuando extendemos una clase, disponemos de todas las declaraciones y métodos de esta última pero podemos crear nuestros propios métodos para ajustarlos a nuestras necesidades.

Trabajando con sobrecarga 

Según la documentación oficial de PHP: La sobrecarga en PHP ofrece los medios para «crear» dinámicamente propiedades y métodos. Estas entidades dinámicas se procesan por los métodos mágicos que se pueden establecer en una clase para diversas acciones. ¿Cómo funciona? veamos un ejemplo extraído de la documentación de PHP.

class PropertyTest
{

    public function __get($name)
    {
        return $name;
    }
}

$obj = new PropertyTest;
echo $obj->awesome; // Devuelve "awesome"


El método __get() nos permite crear y obtener de forma dinámica nombres de atributos de una clase. Vamos a aplicar esta lógica dentro de nuestra clase Collector.

class Collector extends Collection
{
    public function __get($name)
    {
        $value = $this->get($name);
        // if array return another collection instance.
        if (is_array($value)) {
            return $this->make($value);
        }
        return $value;
    }
}

Uso de nuestra clase Collector

Vamos a usar una prueba rápida. Desde la consola creamos un nuevo controlador llamado TestController con:

$ php artisan make:controller CollectionController

Dentro de este controlador creamos un nuevo método llamado index() de la siguiente manera:

public function index()
    {
        $array = [
            'name' => 'Joe', 
            'age' => 25, 
            'country' => 'Italy', 
            'job' => [
                'title' => 'PHP Developer', 
                'Company' => 'Styde'
            ]
        ];
        $collection = new Collector($array);
        dd($collection->job->title);
    }

Por supuesto, debemos incluir la nueva clase Collector en la cabecera de nuestro controlador.

use App\Collector\Collector as Collector;

En lugar de crear la colección con el helper collect() vamos a crear una instancia de la clase Collector pasando como parámetro el array que queremos convertir. Como en nuestro caso estamos usando un array multidimensional, entonces el método __get evalua dicho array y si el valor obtenido es a su vez un array, retorna nuevamente una instancia de Collection.

¿Qué quiere decir esto? que si escribimos $user->name obtendremos “joe” pero si escribimos $user->job obtendremos otro objeto con los valores title y company. Por tanto, para mostrar por ejemplo el título del usuario (title) podemos usar $user->job->title. Si queremos ver este resultado desde el navegador debemos crear una nueva ruta.

Route::get('collection', ['as' => 'collection', 'uses' => 'CollectionController@index']);

Ahora ingresamos a url_de_tu_proyecto/collection y obtendremos como resultado

"PHP Developer"

Este pequeño ejemplo es muy útil cuando obtenemos resultados de tipo json provenientes de una API, ya que extendiendo los métodos de la clase Collection podemos convertir ese objeto json a un array y a su vez en una colección para así trabajar con los datos que nos proporcionan la API.

Espero que te haya gustado esta lección, recuerda que si tienes alguna duda puedes dejarla en la sección de comentarios.

Material relacionado

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Modo de mantenimiento en Laravel 5.1 Lección siguiente Bootstrap Sass en Laravel con Elixir y Gulp