Composer en PHP: dependencias, composer.json, vendor y autoloading PSR-4

Después de aprender programación orientada a objetos y MVC, el siguiente paso para trabajar con PHP moderno es conocer Composer, el gestor de dependencias más utilizado en el ecosistema PHP.

Composer permite instalar librerías, administrar versiones y cargar clases automáticamente mediante autoloading.

Además, es una herramienta fundamental para trabajar con frameworks como Laravel.

¿Qué es Composer?

Composer es un gestor de dependencias para PHP.

Permite declarar qué librerías necesita nuestro proyecto y descargarlas automáticamente.

Por ejemplo, en lugar de copiar manualmente una librería dentro del proyecto, podemos instalarla con:

composer require monolog/monolog

Composer se encargará de descargar la librería y sus dependencias.

¿Qué problema resuelve?

Sin Composer, un proyecto podría requerir:

  • descargar librerías manualmente;
  • copiar archivos;
  • resolver dependencias;
  • verificar versiones compatibles;
  • hacer múltiples require.

Composer automatiza gran parte de ese trabajo.

Comprobar si Composer está instalado

Desde una terminal podemos ejecutar:

composer --version

Si está instalado correctamente, veremos la versión disponible.

Crear un proyecto con Composer

Dentro de una carpeta podemos ejecutar:

composer init

Composer nos hará algunas preguntas y generará un archivo llamado:

composer.json

¿Qué es composer.json?

composer.json contiene la configuración del proyecto y sus dependencias.

Un ejemplo mínimo:

{
    "name": "clubprogramador/ejemplo",
    "require": {
        "php": "^8.2"
    }
}

Instalar una dependencia

Podemos instalar una librería con:

composer require monolog/monolog

Composer modificará composer.json y descargará los paquetes necesarios.

La carpeta vendor

Composer almacena las dependencias dentro de:

vendor/

Por ejemplo:

proyecto/
│
├── app/
├── public/
├── vendor/
├── composer.json
└── composer.lock

¿Qué es composer.lock?

composer.lock registra las versiones exactas de las dependencias instaladas.

Esto permite que distintas personas o servidores instalen exactamente las mismas versiones.

Por eso, en proyectos de aplicaciones, normalmente composer.lock se incluye en el control de versiones.

composer install vs composer update

composer install

composer install

Instala las versiones indicadas en composer.lock.

composer update

composer update

Busca versiones nuevas compatibles con las reglas de composer.json y actualiza composer.lock.

Por eso no conviene ejecutar composer update indiscriminadamente en producción.

Autoloading

Composer genera automáticamente un archivo:

vendor/autoload.php

Podemos cargarlo una sola vez:

<?php

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

?>

A partir de ahí, Composer puede cargar clases automáticamente.

El problema de múltiples require

Sin autoloading podríamos terminar con algo así:

require 'app/Models/Producto.php';
require 'app/Models/Usuario.php';
require 'app/Services/MailService.php';
require 'app/Controllers/ProductoController.php';

A medida que el proyecto crece, esto se vuelve difícil de mantener.

PSR-4

PSR-4 es un estándar utilizado para asociar namespaces con carpetas.

Podemos configurar Composer así:

{
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }
}

Esto significa que las clases cuyo namespace comienza con App\ se buscarán dentro de la carpeta app/.

Ejemplo con namespace

Archivo:

app/Models/Producto.php

Contenido:

<?php

namespace App\Models;

class Producto
{
    public function __construct(
        public string $nombre
    ) {
    }
}

?>

Regenerar el autoload

Después de modificar la configuración de autoload podemos ejecutar:

composer dump-autoload

Usar la clase

Ahora podemos escribir:

<?php

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

use App\Models\Producto;

$producto = new Producto(
    'Teclado'
);

echo $producto->nombre;

?>

No necesitamos hacer un require específico para Producto.php.

Estructura de proyecto con PSR-4

proyecto/
│
├── app/
│   ├── Controllers/
│   │   └── ProductoController.php
│   │
│   ├── Models/
│   │   └── Producto.php
│   │
│   └── Services/
│       └── ProductoService.php
│
├── public/
│   └── index.php
│
├── vendor/
├── composer.json
└── composer.lock

Namespace para un controlador

<?php

namespace App\Controllers;

use App\Models\Producto;

class ProductoController
{
    public function index(): void
    {
        // lógica del controlador
    }
}

?>

Instalar paquetes de desarrollo

Algunas dependencias solo se necesitan durante el desarrollo.

Podemos instalarlas con:

composer require --dev paquete/nombre

Estas dependencias se guardan dentro de:

require-dev

Versiones en Composer

Composer permite indicar restricciones de versiones.

Por ejemplo:

"monolog/monolog": "^3.0"

El operador ^ permite instalar actualizaciones compatibles dentro de la misma versión mayor, según las reglas de versionado semántico aplicables al paquete.

Packagist

Packagist es el repositorio público principal de paquetes utilizados por Composer.

Cuando ejecutamos:

composer require proveedor/paquete

Composer normalmente busca ese paquete en Packagist.

No subir vendor al repositorio

En muchos proyectos PHP se agrega:

/vendor/

al archivo .gitignore.

Las dependencias pueden reconstruirse ejecutando:

composer install

Lo importante es conservar:

  • composer.json;
  • composer.lock.

Ejemplo de .gitignore

/vendor/
.env

También es habitual excluir archivos con configuraciones sensibles como .env.

Composer y MVC

Podemos mejorar el proyecto MVC de la guía anterior eliminando los require manuales.

Antes:

require 'Producto.php';
require 'ProductoController.php';

Después:

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

use App\Models\Producto;
use App\Controllers\ProductoController;

Composer no es solamente para frameworks

Aunque Laravel utiliza Composer intensivamente, también es muy útil en proyectos PHP propios.

Podemos utilizar paquetes para:

  • enviar emails;
  • generar PDFs;
  • trabajar con archivos Excel;
  • manejar logs;
  • consumir APIs;
  • crear tests;
  • procesar fechas;
  • trabajar con variables de entorno.

Buenas prácticas

  • versionar composer.json y composer.lock;
  • no modificar manualmente archivos dentro de vendor;
  • utilizar autoload PSR-4;
  • mantener namespaces consistentes con la estructura de carpetas;
  • revisar las dependencias antes de instalarlas;
  • actualizar paquetes de manera controlada;
  • no ejecutar composer update en producción sin comprender el impacto.

Errores comunes

  • olvidar ejecutar composer install después de clonar un proyecto;
  • eliminar composer.lock sin motivo;
  • editar archivos dentro de vendor;
  • configurar mal el namespace PSR-4;
  • olvidar ejecutar composer dump-autoload después de ciertos cambios;
  • confundir composer install con composer update;
  • subir credenciales o secretos al repositorio.

Ejercicio práctico

Tomá el proyecto MVC de la guía anterior y adaptalo para utilizar Composer.

El objetivo es:

  1. crear un archivo composer.json;
  2. configurar App\ con PSR-4;
  3. agregar namespaces a Modelos y Controladores;
  4. eliminar los require individuales;
  5. cargar solamente vendor/autoload.php;
  6. ejecutar composer dump-autoload;
  7. comprobar que el CRUD siga funcionando.

¿Qué sigue?

Con POO, MVC y Composer ya tenemos gran parte de la base conceptual necesaria para comprender un framework PHP moderno.

La próxima guía puede ser una introducción a Laravel desde cero:

  • qué es Laravel;
  • cómo instalarlo;
  • estructura del proyecto;
  • rutas;
  • controladores;
  • Blade;
  • modelos;
  • migraciones.

¿Te sirvió esta guía? ☕

Si este contenido te ayudó y querés apoyar a Club Programador para seguir publicando ejercicios, proyectos y guías gratuitas, podés colaborar mediante:

☕ Apoyar con Mercado Pago

🌎 Apoyar con PayPal