
Descarga el instalador, compara su hash SHA-384 con el publicado en composer.github.io/installer.sig y ejecútalo hacia /usr/local/bin/composer. Versiona composer.lock e ignora vendor/. En producción, composer install --no-dev --optimize-autoloader, nunca composer update y nunca sudo.
Composer es el gestor de dependencias de PHP. Instala las bibliotecas que un proyecto necesita, resuelve sus propias dependencias, fija las versiones y genera la carga automática de clases. Este tutorial cubre la instalación en los tres sistemas, los comandos del día a día y los errores que cuestan tiempo. Comprobado con Composer 2.10.3 sobre PHP 8.5.10.
Instalar, verificando la firma
La receta que se ve en todas partes es curl -sS https://getcomposer.org/installer | php. Ejecuta directamente un archivo descargado, sin comprobar nada. El procedimiento oficial compara el hash SHA-384 del script con el que publica el proyecto antes de lanzarlo.
#!/usr/bin/env bash
set -euo pipefail
ATTENDU=$(curl -sS https://composer.github.io/installer.sig)
curl -sS https://getcomposer.org/installer -o composer-setup.php
CALCULE=$(php -r "echo hash_file('sha384', 'composer-setup.php');")
if [ "$ATTENDU" != "$CALCULE" ]; then
>&2 echo 'ERREUR : signature invalide, ne pas exécuter'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer
rm composer-setup.php
composer --versionComposer version 2.10.3 2026-08-27 13:34:23Los dos hashes coinciden: el instalador es auténtico. Son treinta segundos de trabajo extra frente a ejecutar un script arbitrario con los permisos de tu cuenta.
Windows
Descarga y ejecuta Composer-Setup.exe. El instalador detecta PHP, configura el PATH y se actualiza solo.
macOS
El script de arriba funciona tal cual. Con Homebrew:
brew install composerUna precisión sobre los tutoriales más antiguos: piden añadir un alias en ~/.bash_profile. Desde macOS Catalina (2019) el shell por defecto es zsh, y ese archivo ya no se lee. El archivo que hay que tocar es ~/.zshrc. Y el alias tampoco hace falta si composer.phar está instalado en /usr/local/bin/composer con permiso de ejecución.
Linux
sudo apt-get update
sudo apt-get install -y php-cli unzip curl
# luego el script de verificación de arribaEl paquete composer de los repositorios de Debian y Ubuntu suele ir varias versiones por detrás. Es preferible el instalador oficial.
Arrancar un proyecto
mkdir mon-projet && cd mon-projet
composer init # cuestionario interactivo
composer require monolog/monologEste comando crea o actualiza tres cosas:
composer.json, lo que tú pides. Se versiona.composer.lock, las versiones exactas instaladas, hasta el commit. También se versiona: es lo que garantiza que todo el equipo y producción tengan el mismo código.vendor/, los archivos descargados. No se versiona, va en el.gitignore.
/vendor/install o update: la distinción que importa
| Comando | Qué hace | Dónde usarlo |
|---|---|---|
composer install | Instala exactamente lo que dice composer.lock | Producción, integración continua, alta de alguien en el equipo |
composer update | Busca versiones más recientes y reescribe composer.lock | Equipo de desarrollo, nunca en producción |
Lanzar composer update en un servidor de producción instala versiones que nadie ha probado. Es la causa de un número notable de puestas en producción fallidas.
# Actualizar un solo paquete
composer update monolog/monolog
# Actualizar un paquete y sus dependencias
composer update monolog/monolog --with-dependencies
# Ver qué cambiaría, sin cambiar nada
composer update --dry-runLas restricciones de versión
{
"require": {
"php": ">=8.2",
"monolog/monolog": "^3.5",
"symfony/console": "~6.4.0",
"vendor/paquet": "2.1.3"
}
}| Escritura | Permite | Rechaza |
|---|---|---|
^3.5 | 3.5, 3.6, 3.99 | 4.0 |
~6.4.0 | 6.4.0, 6.4.9 | 6.5.0 |
6.4.* | de 6.4.0 a 6.4.99 | 6.5.0 |
2.1.3 | solo 2.1.3 | todo lo demás |
El ^ es la opción acertada por defecto: admite las correcciones y los añadidos, y rechaza las rupturas de compatibilidad. Fijar una versión exacta parece prudente, pero bloquea los parches de seguridad.
Declarar la versión de PHP en require evita instalar un paquete que no va a funcionar en el servidor. Y si la máquina de desarrollo no tiene la misma versión que producción, config.platform hace que las dependencias se resuelvan para la versión de destino:
{
"config": {
"platform": {
"php": "8.4.0"
}
}
}La carga automática
Es la función más útil de Composer y la última que se descubre. El estándar PSR-4 asocia un prefijo de espacio de nombres a una carpeta.
{
"autoload": {
"psr-4": {
"App\\": "src/",
"App\\Tests\\": "tests/"
},
"files": [
"src/fonctions.php"
]
}
}Las barras invertidas se duplican en un archivo JSON. Es el error más frecuente en este archivo, y es silencioso hasta el momento en que Composer se niega a leerlo:
"App\": "src/" -> JSON INVALIDE (l'antislash échappe le guillemet)
"App\\": "src/" -> correctCon esta configuración, la clase App\Personnages\Guerrier se busca en src/Personnages/Guerrier.php. La ruta se deduce del nombre, con barras invertidas en el código y barras normales en las carpetas.
<?php
declare(strict_types=1);
namespace App\Personnages; // barras invertidas, nunca barras normales
final class Guerrier
{
// …
}<?php
require __DIR__ . '/vendor/autoload.php';
use App\Personnages\Guerrier;
$conan = new Guerrier();Después de cualquier cambio en la sección autoload:
composer dump-autoloadNada de comentarios en composer.json
JSON no tiene comentarios. Un // colado en el archivo lo vuelve ilegible:
In JsonFile.php line 398:
"./composer.json" does not contain valid JSON
Lexical error on line 5. Comments are not allowed.El comando composer validate revisa el archivo antes de que el problema aparezca en otra parte.
Comprobar las vulnerabilidades
composer audit contrasta los paquetes instalados con la base de avisos de seguridad del ecosistema PHP.
composer auditNo security vulnerability advisories found.Es un comando que hay que colocar en la integración continua, después de composer install: sin carpeta vendor/ solo responde « No installed packages found ». Devuelve un código de salida distinto de cero cuando un aviso afecta al proyecto.
Detectar los paquetes abandonados
Composer avisa de los paquetes cuyo autor ha declarado el abandono, en el momento de la instalación. El aviso pasa a menudo desapercibido en el torrente de la salida:
Package facebook/php-sdk is abandoned, you should avoid using it.
Use facebook/graph-sdk instead.Un paquete abandonado ya no recibe parches, tampoco de seguridad. Ese mensaje merece que te pares en él en lugar de dejarlo pasar.
Desplegar en producción
composer install --no-dev --optimize-autoloader --no-interaction --prefer-dist| Opción | Efecto |
|---|---|
--no-dev | No instala las herramientas de desarrollo (tests, análisis estático) |
--optimize-autoloader | Genera una tabla de correspondencia completa, sin búsqueda en disco en tiempo de ejecución |
--no-interaction | No hace ninguna pregunta |
--prefer-dist | Descarga los archivos comprimidos en lugar de clonar los repositorios |
Y una regla que conviene repetir: no lances nunca Composer con sudo. Los archivos de vendor/ pasarían a pertenecer a root, el servidor web ya no podría leerlos y la caché de Composer acabaría en /root/.composer. Si la instalación global pide sudo, es solo para escribir en /usr/local/bin, una vez.
Los comandos del día a día
# Lo que está instalado
composer show
composer show monolog/monolog # detalle de un paquete
composer show --tree # árbol de dependencias
# Lo que se podría actualizar
composer outdated
composer outdated --direct # solo tus dependencias directas
# ¿Por qué está aquí este paquete?
composer why psr/log
composer why-not symfony/console 7.0 # qué bloquea una subida de versión
# Quitar un paquete
composer remove monolog/monolog
# Reparar una instalación dudosa
rm -rf vendor composer.lock && composer installDos flags de Composer 1 siguen arrastrándose por los tutoriales. composer show -i ya devuelve un aviso, puesto que los paquetes instalados son lo que se muestra por defecto:
You are using the deprecated option "installed". Only installed packages are
shown by default now. The --all option can be used to show all packages.Y composer --V no existe, es -V o --version:
The "--V" option does not exist.Fuentes de paquetes especiales
{
"require": {
"moi/mon-paquet": "dev-main"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/moi/mon-paquet"
}
]
}Para desarrollar un paquete en paralelo al proyecto que lo usa, el repositorio de tipo path crea un enlace simbólico: los cambios se ven al momento, sin reinstalar nada.
{
"repositories": [
{
"type": "path",
"url": "../mes-paquets/mon-paquet",
"options": {
"symlink": true
}
}
]
}Los scripts
{
"scripts": {
"test": "phpunit",
"analyse": "phpstan analyse src --level=8",
"verifier": [
"@analyse",
"@test"
]
}
}composer verifierAsí nadie tiene que recordar las rutas hacia vendor/bin y todo el equipo dispone de los mismos comandos.
Para recordar
- Verifica el hash del instalador antes de ejecutarlo.
- Versiona
composer.lock, ignoravendor/. installen producción,updatesolo en desarrollo.- Duplica las barras invertidas en
composer.json, y ni un comentario. composer auditen la integración continua, nuncasudo.
Composer es la puerta de entrada a la mayoría de las bibliotecas: PHPMailer para enviar un correo y Ratchet para un servidor WebSocket se instalan los dos con composer require.
Para seguir: las buenas prácticas de Composer, las bases de la POO en PHP para sacar partido a la carga automática, y el hub Desarrollo web.
Errores frecuentes
curl … | php ejecuta un archivo descargado sin ningún control. El procedimiento oficial compara su hash SHA-384 antes de lanzarlo."App": "src/" es JSON inválido: la barra invertida escapa la comilla. Hacen falta dos.Lexical error on line 5. Comments are not allowed. JSON no acepta comentarios.composer install, que sigue lo que dice composer.lock.vendor/ pasan entonces a pertenecer a root y el servidor web ya no puede leerlos.The "--V" option does not exist. y You are using the deprecated option "installed". Estos flags vienen de Composer 1.~/.zshrc.

