Composer es un gestor de dependencias, su principal objetivo es mantener las librerías de terceros que utilizamos en un proyecto, estas librerías pueden ser de muchos tipos, desde el core de un framework hasta una paquete que nos permita generar PDF. Con un pequeño archivo en JSON, se definen estas dependencias y las versiones a utilizar. A través de un comando, Composer descarga, actualiza o elimina todo el código fuente de cada una de estas dependencias y también hace la misma comprobación recursivamente para cada uno de los paquetes descargados. Finalmente genera un sistema de autoload que agiliza el uso de las clases externas y nos permite declarar nuestros propios namespaces para así beneficiarnos de la inclusión automática de nuestras clases.

Instalando Composer

Los requisitos de Composer son muy básicos, funciona con la versión 5.3.2+ de PHP. Para realizar determinadas descargas y manipulaciones de archivos nos pedirá que tengamos una instalación de GIT, SVN o HG dependiendo del control de versiones utilizado por el paquete en cuestión. Composer necesita determinadas configuraciones en la compilación del ejecutable PHP, pero yo no me preocuparía, son muy comunes y vienen por defecto en la mayoría de las distribuciones, de todas maneras el installer nos alertará de cualquier incidencia al respecto.

Nos vamos a centrar en hacer la instalación global del paquete, la local es muy parecida, solo tendríamos que hacer la instalación en el directorio de trabajo del proyecto, sin enlazarlo al PATH del sistema. En el caso de estar trabajando sobre una máquina Windows el equipo de Composer ha preparado un ejecutable que instala la ultima versión. Vamos a seguir un poco el proceso desde linea de comandos que en realidad es muy parecido en Linux y Windows, este caso es referido a linux y con el ejecutable php en el PATH.Segun la documentacion oficial:

1
2
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# SHA code verification goes here.

La primera linea descarga una copia del fichero de instalación, después deberíamos verificar la firma SHA para comprobar el paquete, en este caso no la incluyo ya que la firma depende de la versión del instalador, esta deberá consultarse en la página oficial de Composer.

Si deseamos indicar el directorio de destino deberemos además incluir estos parámetros, es aconsejable instalarlo globalmente, en un directorio dentro del PATH. También podemos cambiar el nombre del paquete final para no tener que incluir la extensión .phar al invocarlo.

Linux
Al final del proceso de instalación Composer debería tener permisos de ejecución para todos, con lo que no necesitaremos anteponer el comando php, al llamarlo como ejecutable, Composer se encarga sólo de ejecutarse con el intérprete PHP. Durante la instalación, Composer comprueba unos pocos parámetros en el php.ini y nos alerta de las incidencias, tras esta verificación dejará el paquete en el directorio indicado.

1
2
3
4
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
php -r "unlink('composer-setup.php');"

composer -v

Windows
En este caso necesitaremos crear un archivo bat en el mismo directorio que hayamos instalado Composer, también recordar que para poder invocarlo sin utilizar su ruta, debemos incluirlo en un directorio del PATH, o añadir el directorio de instalación de Composer al PATH. Si no es posible, invocaremos el comando Composer utilizando su ruta completa. Suponiendo que lo hayamos descargado a la raíz c:\ :

1
2
3
4
5
6
7
mkdir bin
php composer-setup.php --install-dir=/bin
php -r "unlink('composer-setup.php');"
cd bin
echo @php "%~dp0composer.phar" %*>composer.bat

composer -v

Uso básico, creamos el fichero composer.json

Crearemos este fichero dentro del directorio raíz de nuestro proyecto, este fichero contendrá información del proyecto, de sus autores y sus dependencias. Cuando ejecutemos el comando Composer este esperará encontrar dicho fichero en el directorio de ejecución.

En nuestro ejemplo vamos a utilizar solo tres de todas las propiedades posibles, en este enlace encontrareis la referencia a todas, autores, licencia, etc…

Siguiendo el ejemplo de la web oficial vamos a crear un proyecto nuevo que va a depender de monolog, una librería para generar diferentes logs que respeta el standard PSR-3 Logger interface.

1
2
3
4
5
6
7
{
"name": "mbarquin/composer-example",
"description": "Descripción de una linea del proyecto o paquete",
"require": {
"monolog/monolog": "1.0.*"
}
}

name
El nombre del proyecto, no es obligatorio, se utiliza para identificarlo y para que puede ser requerido como dependencia por otros paquetes. Es un nombre compuesto, separado por una barra / . La primera partícula será nuestro vendor name (nombre de proveedor), común a nuestros distintos desarrollos (paquetes). Generalmente se suele utilizar el de usuario de Github. La siguiente partícula será el nombre específico del paquete/proyecto actual a desarrollar. Para el nombre del paquete se ignoran mayúsculas / minúsculas y se aceptan palabras separadas por guiones en vez de espacios. Los proyectos más populares suelen utilizar su propio nombre de paquete como nombre de proveedor, facilitando así su localización y su división en distintos paquetes más pequeños.

description
Descripción corta del proyecto o paquete, generalmente de una linea, solo es obligatoria si el paquete es publicado.

require
Es la propiedad que indica a Composer cuales son las dependencias del proyecto. Es un array, indizado por el nombre del paquete y como valor la versión deseada, en la forma "vendor/package-name": "version".

El nombre de las dependencias respetará las mismas convenciones definidas anteriormente para nuestro proyecto. Un nombre de proveedor separado por una / del nombre del paquete. Esta dependencia deberá estar declarada en Packagist que es un repositorio donde Composer busca los paquetes de los que desconoce el origen. En otros casos podemos indicar a Composer una lista de repositorios donde obtener directamente las dependencias.

La versión puede ser expresada de múltiples formas, en realidad Packagist y Composer obtendrán las versiones disponibles de las distintas branches y tags que hayan sido declaradas en el repositorio de origen. Se puede usar el comodín * para sustituir un número de versión concreto, como por ejemplo “1.0.*” para obtener una versión >=1.0 y <1.1. También podemos indicar el numero de versión anteponiendo el carácter ^ que representa versión compatible, así “^2.0” nos instalará la versión más reciente compatible con nuestro requisito. Aquí una pequeña muestra de lo configurable que puede llegar a ser este parámetro

  • ">=1.0 <1.7 || >=2.0" Mayor igual que 1.0 y menor que 1.7 o mayor igual que 2.0
  • "1.1 - 2.0" Mayor igual que 1.1 y menor que 2.1
  • "1.0.*", Mayor igual que 1.0.0 y menor que 1.1.0
  • "^2.0", Compatible con 2.0
  • "~1.2.3", Mayor igual que 1.2.3 y menor que 1.3.0

Tambien podremos instalar directamente branches o versiones etiquetadas como -dev o -rc, se puede ver con más detalle aquí .

Esta sección acepta también referencias a versiones especificas de PHP o extensiones del mismo que el proyecto pueda necesitar para su funcionamiento, aunque jamás se descargará nada de estas, se espera que estén disponibles en el momento de su ejecución.

1
2
3
4
5
6
7
{
"require" : {
"php" : "^5.5 || ^7.0",
"ext-mbstring": "*",
"monolog/monolog": "1.0.*"
}
}

Instalando los paquetes, composer.lock

Con esto ya tenemos un fichero composer.json funcional que nos va a permitir descargar la librería monolog a nuestro proyecto. Las dependencias por defecto se instalaran en la carpeta vendor (si no existe se crea automáticamente), dentro del mismo directorio donde esta alojado el archivo json. En la raíz del proyecto, al mismo nivel, ejecutamos el comando: composer install.

composer.lock
Al final de la primera instalación, se generará en el directorio un archivo denominado composer.lock. Este fichero guarda la relación de las versiones exactas instaladas. Siempre que esté disponible, Composer lo utilizará en vez del .json para descargar las mismas versiones de las dependencias que la primera vez. Si queremos que se actualicen las dependencias a la ultima versión posible y a su vez se actualice el fichero .lock, debemos invocar el comando composer update. Es interesante meter este fichero .lock al control de versiones que utilicemos, para que cualquier otra persona que vaya a desarrollar tenga las mismas versiones de las librerías. Se pueden actualizar los paquetes independientemente añadiendo al comando los nombres de los que deseemos actualizar. composer update monolog/monolog ...

Autoload

Una de las grandes ventajas de utilizar Composer es que automáticamente genera un sistema de autoload basado en namespaces, compatible tanto con PSR-0 como con PSR-4. Incluyendo solamente el fuente autoload.php podremos invocar directamente a las distintas clases requeridas a través de su namespace, sin tener que hacer los requires o includes pertinentes.

1
2
3
4
5
6
7
<?php

require __DIR__ . '/vendor/autoload.php';

$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

También nuestro proyecto puede beneficiarse de este sistema, basta con añadir al archivo composer.json la entrada autoload, que registrara el loader para el namespace a través de autoload.php:

1
2
3
4
5
6
7
8
9
{
"name": "mbarquin/composer-example",
"require": {
"monolog/monolog": "1.0.*"
},
"autoload": {
"psr-4": {"ComposerExample\\": "src/"}
}
}

Con lo cual podríamos instanciar las clases dentro de la carpeta src mediante el namespace.

1
2
3
4
<?php
require __DIR__ . '/vendor/autoload.php';

$test = new ComposerExample\Test();

Cada vez que hagamos un cambio en esta sección podremos regenerar los fuentes encargados del autoload con el comando composer dump-autoload.

Development

A fin de facilitar las tareas del desarrollo, al mismo nivel que require o autoload, podemos declarar las secciones require-dev y autoload-dev. Estas se encargan de gestionar dependencias suplementarias que pueden ser necesarias durante esta etapa, como las librerías para tests unitarios, CI o cualquier otra cosa. Una vez incluidas estas directivas indicaremos a Composer que estamos haciendo una install para producción con el parámetro composer install --no-dev y así evitar estos paquetes suplementarios. Por defecto, si están definidas las propiedades, Composer descargará las dependencias y generará las clases de autoload tanto para dev como para no-dev .

Finalizando…

Hemos visto un poco por encima el funcionamiento básico, el comando tiene muchos parámetros y se puede trabajar directamente con él en vez de editar constantemente el archivo. Viendo la documentación online enseguida aprenderemos todo lo necesario para dominarlo. Casi todos los proyectos a día de hoy lo utilizan, además los IDE’s como Netbeans ya aceptan plugins para integrarlo.