Inicializa un proyecto PHP usando composer
Tags: php, composer, code
Published: 2020-06-25 00:58:13

Si tienes alguna idea novedosa, o simplemente te gustaría mejorar alguna librería existente agregando alguna funcionalidad o haciendola compatible con tu framework favorito entonces este post es para ti.

El proceso de construcción de una librería puede variar dependiendo de tus requerimientos, pero en esta guia te compartiré los primeros pasos para inciar tu proyecto utilizando composer. El contenido de éste post se resume en:

- ¿Qué es composer?
- Requisitos de la guía.
- Inicializando el proyecto.
- Registrar el namespace de nuestro proyecto en composer
- Crear un archivo de utilerías y registrarlo en composer.



## ¿Qué es composer?

Composer es una herramienta que nos ayuda a gestionar las dependencias de nuestro proyecto, siendo éstas librerías externas o simplemente ficheros o clases internas. Composer se encarga desde la instalación de dependencias externas hasta la integración de nuestras clases o funciones, se basa en el uso de las convenciones PSR de PHP para logar su objetivo. Sí quieres saber más de composer o de PSR puedes revisar los siguientes links:

- Página oficial de composer: https://getcomposer.org/
- Convenciones PSR: https://www.php-fig.org/psr/



## Requisitos de la guia.

El único requerimiento para seguir ésta guía es tener PHP instaldo y una copia composer (ejecutable o instalada) en tu computadora, para más detalles revisa [la documentación oficial](https://getcomposer.org/download/).



## Inicializar el proyecto.

Para comenzar a trabajar en un proyecto, crearemos una carpeta con la siguiente estructura:

```
libreria/
|--- src/
|--- README.md
|--- composer.json
```



### src

La carpeta `src` será la  encargada de contener todo el código de nuestro proyecto, y aunque no es obligatorio que la carpeta de llame `src`, es una buena práctica ya que la mayoría de los desarrolladores están acostumbrados a manejarlo de esta manera.



### README.md

Este es uno de los archivos más importantes de tu proyecto, se trata de un documento que contiene la definición completa de tu ibrería, notas de instalación, de uso, futuros planes, entres otros. Prácticamente es la carta de presentación de tu librería. 

El archivo `README` está escrito en `markdown` y por ahora puedes dejarlo en blanco, o si gustas, puedes escribir algo como lo sieguiente:

```
# Mi fabulosa librería

Esta librería se encarga de...

## Requerimientos

- composer
- php 5.6 o posterior

## Instalación

​`composer require javleds/fabulosa-libreria `
```



### Composer.json

El archivo `composer.json`  es el más importante de esta guia. Este archivo será el encargado de gestionar las dependencias de nuestro proyecto, cómo habrás notado, se trata de un archivo `json`, el cuál debe tener por lo menos las siguientes entradas:

> **Nota**: Para éste ejemplo en concreto utilizaremos mis datos personales al igual usuario de github (`javleds`) y llamaremos `FabulosaLibreria` al proyecto, en tu caso asegurate de cambiar estos datos.

```json
{
  "name": "javleds/fabulosa-libreria",
  "description": "Mi fabulosa librería",
  "type": "library",
  "authors": [
    {
      "name": "Javier Ledezma",
      "email": "contact@javierledezma.com"
    }
  ],
  "version": "1.0",
  "license": "MIT"
}
```

Cuyas entradas son:

-  `name`: Nombre de la librería conformada de 2 partes separadas por una diagonal (`/`):

  - Autor, empresa o usuario de git.
  - Nombre de la librería usando.

  > Nota: Es muy importante éste nombre, ya qué será utilizado posteriormente para poder utilizarla en otros proyectos, utilizando `composer require autor/nombre-libreria `

- `description`: Una descripción corta de lo que hace tu librería.

- `type`: Define el tipo de proyecto, puede ser de diversos tipos: library, project, metapackage o composer-plugin.

- `authors`: Lista de autores que participan en el desarrollo del proyecto.

- `version`: Versión actual del proyecto.

- `license`: Licencia del proyecto, en general te recomiendo darle una leída a las [licencias existentes](https://en.wikipedia.org/wiki/Software_license), pero si quieres que tu libreŕia sea open source, puede utiliza `MIT` o `BSD`. 

Una vez que tenemos definidos éstos campos ya tenemos una liberería declarada en composer.



## Registrar el nombre de espacio de nuestro proyecto en composer

Para lograr que nuestras clases de php sean cargadas de manera automática en nuestro proyecto será necesario registrar un nombre de espacio ( o `namespace`) en el archivo `composer.json`. 

Un nombre de espacio es lo equivalente a un `directorio virtual`, nos sirve para darle un identificador único a nuestras clases y evitar colisiones con clases similares de otras librerías. Por ejemplo, la clase `User` es utilizada en muchos paquetes, pero puedes diferenciarlas a través de un espacio de nombre. Regularmente el espacio de nombre se compone del usuario de `USUARIO_GIT\NOMBRE_LIBRERIA`, en éste caso usaremos `Javleds\FabulosaLibreria` .

Para llevar ésto a la práctica, crearemos un nuevo archivo en la carpeta `libreria/src` llamado `Mensajes.php` con el siguiente código:

```php
<?php

class Mensajes {
    public function saludar()
    {
        echo 'Bienvenido a mi fabulosa librería!';
    }
}
```

La estructura de nuestro proyecto debería quedar así:

```
libreria/
|--- src/
	|--- Mensajes.php
|--- composer.json
|--- README.md
```

Una vez que hemos creada nuestra primera clase, es necesario registrar nuestro directorio `/src` con el espacio de nombre acordado para que sea reconocido por composer, para ello, editamos el archivo `composer.json` y agregamos la entrada `autoload.psr-4`:

```json
{
  "name": "javleds/fabulosa-libreria",
  "description": "Mi fabulosa librería",
  "type": "library",
  "authors": [
    {
      "name": "Javier Ledezma",
      "email": "contact@javierledezma.com"
    }
  ],
  "version": "1.0",
  "license": "MIT",
  "autoload": {
    "psr-4": {
      "Javleds\\FabulosaLibreria\\": "src/"
    }
  }
}
```

Cuyas nuevas entradas son:

- `autoload`: Le indicamos a composer que queremos que cargue de manera automática todos los registros de esta estrada.

- `psr-4`: Le indíca a composer que todos los archivos dentro de la carpeta `src` que cumplan con el estándar `PSR-4` seán auto-registradas con el namespace `Javleds\FabulosaLibreria`. Nota que las diagonales invertidas (`\`) deben ser escapadas utilizando doble diagonal invertida (`\\`).

  ```php
  # El estándar PSR-4 determina que la clase de PHP 
  # debe contener el mismo nombre que su archivo contenedor
  # y que los nombres de espacio deben coincidir con los 
  # subdirectorios del proyecto, ejemplos:
  
  # Con directorios:
  
  namespace Javleds\FabulosaLibreria; #debe estár en /src
  namespace Javleds\FabulosaLibreria\Utilerias; #debe estár en /src/Utilerias
  namespace Javleds\FabulosaLibreria\Modelos; #debe estár en /src/Modelos
  namespace Javleds\FabulosaLibreria\Otros\Traits; #debe estár en /src/Otros/Traits
  
  # Con clases:
  
  namespace Javleds\FabulosaLibreria;
  class Mensajes {...} #debe estár en /src/Mensajes.php
  
  namespace Javleds\FabulosaLibreria\Utilerias;
  class Numeros {...} #debe estár en /src/Utilerias/Numeros.php
  
  namespace Javleds\FabulosaLibreria\Modelos; 
  class Usuario {...} #debe estár en /src/Modelos/Usuario.php
  
  namespace Javleds\FabulosaLibreria\Otros\Traits; 
  trait Notificable {...} #debe estár en /src/Otros/Traits/Notificable.php
  
  ```

> **Nota importante**: Después de modificar el archivo composer.json, debemos indicarle a composer que actualice la información, para ello ejecutamos el comando `composer dump-autoload`

Una vez registrado el `namespace` de nuestra librería, debemos indicarle a nuestra clase `Mensajes` que pertenece a ese `namespace`, para ello, editaremos el archivo `src/Mensajes.php` y agregaremos la siguiente línea:

```php
<?php

namespace Javleds\FabulosaLibreria; // <-- Aquí indicamos el namespace
    
class Mensajes {
    public function saludar()
    {
        echo 'Bienvenido a mi fabulosa librería!';
    }
}
```

> **Importante**: El `namespace` debe ser la primera línea de código de nuestro archivo PHP



Finalizado éste proceso de registro, ahora podemos hacer uso de la clase `Mensajes` en cualquier proyecto de la siguiente manera:

```php
$mensajes = new Javleds\FabulosaLibreria\Mensajes();
$mensajes->saludar();

# O si lo prefieres:

use Javleds\FabulosaLibreria\Mensajes;

$mensajes = new Mensajes();
$mensajes->saludar();
```

Si necesitaramos crear más archivos dentro de la carpeta `src` solo debemos seguir las convenciones `PSR-4` mencionadas anteriormente, por ejemplo, crearemos el archivo `src/Utilerias/Calculadora.php` con lo siguiente:

```php
<?php

namespace Javleds\FabulosaLibreria\Utilerias; // <-- Sub-namespace Utilerias
    
class Calculadora {
    /**
     * @param int $num1
     * @param int $num2
     *
     * @return int
     */
    public function sumar($num1, $num2)
    {
        return $num1 + $num2;
    }
}
```

Estructura del proyecto:

```
libreria/
|--- src/
	|--- Mensajes.php
	|--- Utilerias/
		|--- Calculadora.php
|--- composer.json
|--- README.md
```

Y cuyo uso sería:

```php
$calculadora = new Javleds\FabulosaLibreria\Utilerias\Calculadora();
$calculadora->sumar(1, 2); // regresa: 3

# O si lo prefieres:

use Javleds\FabulosaLibreria\Utilerias\Calculadora;

$calculadora = new Calculadora();
$calculadora->sumar(1, 2); // regresa: 3
```



Para utilizar ésta clase no es necesario editar el archivo `composer.json` ni ejecutar el comando `composer dump-autoload` porque el sirectorio `src` ya está registrado en composer.



## Crear un funciones globales y registrarlas en composer

Si lo que deseas es tener funciones disponibles a lo largo de todo tu proyecto, puedes crear un archivo php que contenga dichas funciones y regsitrarlo en composer, para ejemplificarlo, crearemos el archivo `src/funciones_globales.php` con lo siguiente:

```php
<?php

   
if (! function_exists('elementoAleatorio')) {
    /**
     * @param array $elementos
     *
     * @return mixed
     */
    function elementoAleatorio($elementos)
    {
        $valorMaximo = count($elementos) - 1;
        $indiceAleatorio = rand(0, $valorMaximo);
        return $elementos[$indiceAleatorio];
    }
}

```

Estructura del proyecto:

```
libreria/
|--- src/
	|--- funciones_globales.php
	|--- Mensajes.php
	|--- Utilerias/
		|--- Calculadora.php
|--- composer.json
|--- README.md
```

Una vez creado debemos registrarlo en nuestro archivo `composer.json` agregando la entrada `autoload.files` como se muestra a continuación:

```json
{
  "name": "javleds/fabulosa-libreria",
  "description": "Mi fabulosa librería",
  "type": "library",
  "authors": [
    {
      "name": "Javier Ledezma",
      "email": "contact@javierledezma.com"
    }
  ],
  "version": "1.0",
  "license": "MIT",
  "autoload": {
    "psr-4": {
      "Javleds\\FabulosaLibreria\\": "src/"
    },
    "files": [
      "src/funciones_globales.php"
    ]
  }
}
```

> **Nota**: No olvides ejecutar `composer dump-autoload` para obtener los últimos cambios del archivo `composer.json`

Al agregar esta entrada las funciones contenidas en el archivo `src/funciones_globales.php` se cargarán automáticamente y estarán disponibles en todo el proyecto. A diferencia de la entrada `psr-4`, la entrada `files` solo puede mapear un solo archivo, por lo que será necesario editar esta entrada cada que requieras agregar más archivos php con funciones globales.

Para utilizar nuestra función en cualquier parte del proyecto solo debemos invocarla desde cualquier lado que sea necesaria de la siguiente manera:

```php
elementoAleatorio([1, 2, 3, 4, 5]); // regresa un elemento aleatorio entre 1-5
elementoAleatorio(['a', 'b', 'c']); // regresa un elemento aleatorio entre a-c
```



## Conclusión

Composer es una herramienta que nos ayuda bastante a desarrollar proyectos reutilizables, haciendo un buen uso de él podemos escalar nuestros proyectos muy fácil. Te invito a comiences a trabajar una idea propia o mejorar algúna que ya existe. Si ya lo has hecho, compartenos tu experiencia en los comentarios.