Composer y PSR-4
Composer es el gestor de dependencias estándar de PHP. Además de instalar librerías, genera un autoloader optimizado que sigue el estándar PSR-4, el estándar de la industria para autoloading.
¿Qué es Composer?
Composer es una herramienta que gestiona las dependencias de tu proyecto PHP. Permite:
- Instalar librerías de terceros (como PHPUnit, Monolog, etc.)
- Gestionar versiones y actualizaciones
- Generar un autoloader para tu código y las dependencias
Instalar Composer
Descarga e instala Composer desde getcomposer.org. Verifica la instalación:
composer --version
# Composer version 2.x.x
Iniciar un proyecto con Composer
Crea un nuevo proyecto e inicializa Composer:
mkdir mi-proyecto
cd mi-proyecto
composer init
Composer te hará preguntas sobre tu proyecto.
Puedes aceptar los valores por defecto o
personalizar. Esto crea
composer.json:
{
"name": "tu-usuario/mi-proyecto",
"description": "Mi proyecto PHP",
"type": "project",
"require": {
"php": ">=8.1"
}
}
Configurar PSR-4 autoloading
PSR-4 es el estándar que define cómo mapear
namespaces a directorios. Añade la configuración
de autoload a composer.json:
{
"name": "tu-usuario/mi-proyecto",
"description": "Mi proyecto PHP",
"type": "project",
"require": {
"php": ">=8.1"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Esta configuración dice: "El namespace
App\ corresponde al directorio
src/".
Generar el autoloader
Después de configurar el autoload, genera los archivos necesarios:
composer dump-autoload
Esto crea la carpeta vendor/ con el
autoloader. Ahora la estructura es:
mi-proyecto/
├── composer.json
├── composer.lock
├── vendor/
│ └── autoload.php # Este es el autoloader
└── src/ # Aquí va tu código (App\)
Usar el autoloader de Composer
Solo necesitas un require al
autoloader de Composer:
<?php
// index.php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use App\Models\Usuario;
use App\Services\AuthService;
// Las clases se cargan automáticamente
$usuario = new Usuario(1, 'ana@example.com');
$auth = new AuthService();
Ejemplo práctico con PSR-4
<?php
// src/Models/Usuario.php
namespace App\Models;
declare(strict_types=1);
class Usuario
{
public function __construct(
public readonly int $id,
public readonly string $email,
public readonly string $nombre = ''
) {}
public function saludo(): string
{
$nombre = $this->nombre ?: 'Usuario';
return "Hola, $nombre";
}
}
<?php
// src/Services/UsuarioService.php
namespace App\Services;
declare(strict_types=1);
use App\Models\Usuario;
use InvalidArgumentException;
class UsuarioService
{
/** @var Usuario[] */
private array $usuarios = [];
public function registrar(string $email, string $nombre): Usuario
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Email inválido');
}
$id = count($this->usuarios) + 1;
$usuario = new Usuario($id, $email, $nombre);
$this->usuarios[$id] = $usuario;
return $usuario;
}
public function buscar(int $id): ?Usuario
{
return $this->usuarios[$id] ?? null;
}
}
<?php
// index.php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use App\Services\UsuarioService;
$servicio = new UsuarioService();
$ana = $servicio->registrar('ana@example.com', 'Ana García');
$luis = $servicio->registrar('luis@example.com', 'Luis López');
echo $ana->saludo() . "\n"; // Hola, Ana García
echo $luis->saludo() . "\n"; // Hola, Luis López
Autoload para tests
Para tests, usa autoload-dev que
solo se carga en desarrollo:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
Ejecuta composer dump-autoload
después de cambiar la configuración.
Instalar dependencias
Composer también gestiona librerías de terceros. Para instalar una dependencia:
# Instalar una librería
composer require monolog/monolog
# Instalar como dependencia de desarrollo
composer require --dev phpunit/phpunit
Las dependencias se descargan a
vendor/ y el autoloader las incluye
automáticamente:
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Monolog se carga automáticamente
$log = new Logger('app');
$log->pushHandler(new StreamHandler('app.log', Logger::INFO));
$log->info('Aplicación iniciada');
Optimizar para producción
En producción, optimiza el autoloader para mejor rendimiento:
# Genera un classmap optimizado
composer dump-autoload --optimize
# O al instalar dependencias
composer install --optimize-autoloader --no-dev
Añade vendor/ a tu
.gitignore. Las
dependencias se reinstalan con
composer install usando
composer.lock.
Comandos esenciales de Composer
# Inicializar proyecto
composer init
# Instalar dependencias (desde composer.lock)
composer install
# Añadir dependencia
composer require vendor/paquete
# Añadir dependencia de desarrollo
composer require --dev vendor/paquete
# Actualizar dependencias
composer update
# Regenerar autoloader
composer dump-autoload
# Ver dependencias instaladas
composer show
Ejercicios
Ejercicio 1: Proyecto con Composer
Crea un nuevo proyecto con Composer.
Configura PSR-4 para que
App\ apunte a
src/. Crea las clases
App\Models\Tarea y
App\Services\TareaService.
Verifica que el autoloading funciona
creando un index.php que
use ambas clases.
Ver solución
// composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
<?php
// src/Models/Tarea.php
namespace App\Models;
declare(strict_types=1);
class Tarea
{
public function __construct(
public readonly string $titulo,
public bool $completada = false
) {}
}
// src/Services/TareaService.php
namespace App\Services;
declare(strict_types=1);
use App\Models\Tarea;
class TareaService
{
private array $tareas = [];
public function agregar(Tarea $tarea): void
{
$this->tareas[] = $tarea;
}
public function listar(): array
{
return $this->tareas;
}
}
// index.php
require 'vendor/autoload.php';
use App\Models\Tarea;
use App\Services\TareaService;
$service = new TareaService();
$service->agregar(new Tarea('Aprender PHP'));
print_r($service->listar());
Ejercicio 2: Múltiples namespaces
Extiende el proyecto anterior para tener
dos prefijos de namespace:
App\ en src/ y
Tests\ en
tests/. Crea una clase
Tests\Services\TareaServiceTest
que instancie
TareaService.
Ver solución
// composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
<?php
// tests/Services/TareaServiceTest.php
namespace Tests\Services;
declare(strict_types=1);
use App\Models\Tarea;
use App\Services\TareaService;
class TareaServiceTest
{
public function testAgregarTarea(): bool
{
$service = new TareaService();
$tarea = new Tarea('Test');
$service->agregar($tarea);
$tareas = $service->listar();
return count($tareas) === 1
&& $tareas[0]->titulo === 'Test';
}
}
// Ejecutar: composer dump-autoload
Ejercicio 3: Instalar una dependencia
Instala la librería
ramsey/uuid con Composer.
Modifica la clase Tarea
para que genere un UUID automáticamente
al crearse. Consulta la documentación de
la librería para ver cómo usarla.
Ver solución
# Terminal
composer require ramsey/uuid
<?php
// src/Models/Tarea.php
namespace App\Models;
declare(strict_types=1);
use Ramsey\Uuid\Uuid;
class Tarea
{
public readonly string $id;
public function __construct(
public readonly string $titulo,
public bool $completada = false
) {
$this->id = Uuid::uuid4()->toString();
}
}
// Uso
$tarea = new Tarea('Aprender Composer');
echo $tarea->id;
// Ejemplo: 550e8400-e29b-41d4-a716-446655440000
¿Has encontrado un error o tienes sugerencias para esta lección?
Enviar feedback¿Te está gustando el curso?
Tenemos cursos premium con proyectos reales y soporte.
Descubrir cursos premium