PHPackages                             oscarricardosan/mapper - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. oscarricardosan/mapper

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

oscarricardosan/mapper
======================

Paquete PHP que mapea los DocComments de la clase y permite definir mutators y accessors

1.4.0(9y ago)04.2k1MITPHPPHP &gt;=5.6.4

Since Mar 1Pushed 9y ago1 watchersCompare

[ Source](https://github.com/oscarricardosan/mapper)[ Packagist](https://packagist.org/packages/oscarricardosan/mapper)[ RSS](/packages/oscarricardosan-mapper/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (1)Versions (6)Used By (1)

\#Mapper

Paquete PHP agnóstico a frameworks provee una forma fácil con la cual mapear los atributos especificado en los DocComments de una clase, también permite agregar funcionalidad extra a través de mutators y accesors (setNameAttribute, getNameAttribute) al estilo de los Modelos de Laravel.

\##1. Por qué Mapper?

> El Principio de lo Explicito establece: Intenta siempre favorecer lo explícito sobre lo implícito.

Ser explicito a la hora de hacer código es algo que ayudara a quien hace el código y a sus posibles sucesores a la hora de entender que es lo que esta pasando. Ejemplo:

```
    class Customer{
        public function store($name, $city){
            .....
        }

    }

```

Pero cuando tenemos un objeto con demasiados atributos ya no es tan fácil. **¡NO! la solución no es crear una función con más de 10 atributos.** , en la mayoría de casos la solución es pasar un array con todos los atributos. Algo así:

```
    class Customer{
        public function store(array $data){
            //En laravel
            $customer = new Customer();
            $customer->fill($data);
            $customer->save();
        }

    }

```

Sin embargo, esto no es para nada explicito, cualquiera que llegue tendrá que hacer seguimiento para poer entener que es lo que esta llegando en el array $data.

Con Mapper podrías hacer:

```
    class Customer{
        public function store(CustomerMap $customerMap){

            //Option A
            $customer = new Customer();
            $customer->name = $customerMap->name;
            $customer->city = $customerMap->city;
            $customer->country = $customerMap->country;
            .....
            $customer->save();

            //Option B
            $customer = new Customer();
            $customer->fill($customerMap->getAttributes());
            $customer->save();
        }

    }

```

\##2. Instalación

Ejecutar en consola

`composer require oscarricardosan/mapper`

\##3. Uso

\###3.1. Definir una clase que extienda Mapper y tenga DocComments

Crea una clase que extienda a Mapper y en DocComments define las propiedades que van a ser mapeadas:

```
use Oscarricardosan\Mapper\Mapper;

/**
 * @property $name
 * @property $company "PHP Company"
 * @property $document_type
 * @property $document_number
 * @property $city
 * @property $state
 * @property $country
 * @property $car
 */

class CustomerMap extends Mapper
{

}

$customerMap = new CustomerMap();

```

Con lo anterior **$customerMap** ha quedado con las propiedades que estaban en los DocComments incluyendo los valores por defecto:

```
    echo($customerMap->company);  => "PHP Company"
    echo($customerMap->name);  => null

```

\###3.2. Cargar valores

Existen dos formas para cargar valores a una clase que extiende de Mapper:

\####3.2.1. Forma masiva

Ya sea por el \_\_construct o por setAttributesFromArray, si la propiedad que viene en el array no esta declarada en los DocComments el la omitirá.

```
    $sample = [
        'name' => 'oscar',
        'document_type' => 'cc',
        'document_number' => '000255',
        'country' => 'Colombia',
        'city' => 'Moscú',
        'state' => 'Bogota',
        'car' => 'toyota',
    ];

```

Desde el constructor

```
    $customerMap = new CustomerMap($sample);
    echo($customerMap->name);  => oscar

```

Con el método **setAttributesFromArray**

```
    $customerMap = new CustomerMap();
    $customerMap->setAttributesFromArray($ssample);
    echo($customerMap->name);  => oscar

```

\####3.2.2. Como propiedad

```
    $customerMap = new CustomerMap();
    $customerMap->name  = 'oscar';
    echo($customerMap->name);  => oscar

```

**NOTAS:**

- Si asignas un valor a una propiedad que no esta definida en los DocComments no tendrá efecto y la propiedad retornara null.

> ```
>    $customerMap->otherProperty = 'value';
>    var_dump($customerMap->otherProperty);  => NULL
>
> ```

- Los valores por defecto establecidos en DocComments permaneceran hasta que no los remplazes ya sea por un array\[\] o de forma directa -&gt;.

> ```
>    echo($customerMap->company);  => PHP Company
>    $customerMap->company = 'Cbot'
>    echo($customerMap->company);  => Cbot
>
> ```

\###3.3. Mutators y Accessors

Siguiendo la sintaxis de los modelos en Laravel podemos declarar mutators y accessors en la clase que extiende Mapper. En ellos puedes dejar la lógica para depurar los datos que generalmente nos llegan por request y que se pierde en el controlador al no ser reutilizable.

```
use Oscarricardosan\Mapper\Mapper;

/**
 * @property $name
 * @property $company "PHP Company"
 * @property $document_type "cc"
 * @property $document_number
 * @property $city
 * @property $state
 * @property $country
 * @property $car
 */
class CustomerMap extends Mapper
{
    public function getDocumentTypeAttribute($value)
    {
        return strtoupper($value);
    }
    public function setCityAttribute($value)
    {
        if($value == 'Moscú')
            $this->attributes['country'] = 'Rusia';
    }
}

//Accessor default value
echo($customerMap->document_type);  => CC

//Accessor new value
$customerMap->document_type = 'ti';
echo($customerMap->document_type);  => TI

//Mutator
$customerMap->city = 'Moscú';
echo($customerMap->country);  => Rusia

```

\###3.4. Alias

En ocaciones leemos datos desde un csv, excel u otros donde los datos de entrada vienen en vector el cual PHP covierte en una array con clave númerica. Para ello mutator permite establecer alias a las propiedades. Para usarlo solo debes usar la propiedad $alias de la clase que extiende mapper y !listo¡, con ellos los mutator y accessors funcionan comun y corriente, con lo cual no solo mapeas el vector y lo a asignas a su correspondiente propiedad sino que también lo puedes validar.

```
/**
 * @property $name
 * @property $car
 * @property $document_type
 */
class CustomerMap extends Mapper
{
    protected $alias = [
        0 => 'name',
        1 => 'car',
        2 => 'document_type'
    ];
    public function getDocumentTypeAttribute($value)
    {
        return strtoupper($value);
    }
}

//Passing vector
$customerMap = new CustomerMap(['Oscar', 'Tesla S', 'ti']);
echo($customerMap->name);  => Oscar
echo($customerMap->car);  => Tesla S
echo($customerMap->document_type);  => TI

```

\##4. Ejemplo usando un Controlador y un Repositorio

```
    #Laravel

    /***
       * REPOSITORY
    ***/
    class CustomerRepository{
        public function store(CustomerMap $customerMap)
        {
            $customer = new Customer();
            $customer->fill($customerMap->getAttributes());
            $customer->save();
        }
        public function update(CustomerMap $customerMap)
        {
            $customer = new Customer();
            $customer->name = $customerMap->name;
            $customer->name = $customerMap->company;
            $customer->save();
        }
    }

    /***
       * CONTROLLER
    ***/
    class CustomerController{
        $repository;
        public function __construct(){
            $this->repository =  new CustomerRepository();
        }

        public function store($request)
        {
           $customerMap = new CustomerMap($request->all());
           $this->repository->store($customerMap);
        }

        public function update($request)
        {
           $customerMap = new CustomerMap($request->all());
           $this->repository->update($customerMap);
        }
    }

```

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

5

Last Release

3348d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f1213aa6d5681bcbc79b6148c307a936cf64a1acead102fa12f0032dacc730fd?d=identicon)[oscarricardosan](/maintainers/oscarricardosan)

---

Top Contributors

[![oscarricardosan](https://avatars.githubusercontent.com/u/1308027?v=4)](https://github.com/oscarricardosan "oscarricardosan (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/oscarricardosan-mapper/health.svg)

```
[![Health](https://phpackages.com/badges/oscarricardosan-mapper/health.svg)](https://phpackages.com/packages/oscarricardosan-mapper)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
