Introduzione
Quando si lavora con PHP e Composer, spesso ci si concentra solo su require, autoload e composer.lock. Però Composer offre un altro strumento molto utile e spesso sottovalutato: gli script collegati agli eventi del ciclo di vita del progetto.
In pratica, Composer può eseguire automaticamente comandi PHP o shell in momenti precisi, ad esempio dopo un’installazione o dopo un aggiornamento delle dipendenze. Questo è estremamente comodo per attività ripetitive come:
- creare cartelle necessarie al progetto;
- pulire cache o file temporanei;
- generare configurazioni di base;
- eseguire controlli preliminari;
- lanciare piccoli task di manutenzione.
In questo tutorial vedremo un caso pratico e utile: usare gli script di Composer per preparare automaticamente l’ambiente del progetto dopo installazione e aggiornamento. È un sotto-argomento molto concreto, perfetto per chi vuole rendere il proprio flusso di lavoro più affidabile e meno manuale.
Codice completo
Immaginiamo un piccolo progetto PHP che, dopo composer install o composer update, debba:
- creare una cartella var/log se non esiste;
- creare una cartella var/cache se non esiste;
- scrivere un file .env.local di esempio se manca;
- stampare un messaggio finale utile allo sviluppatore.
Ecco un esempio completo di composer.json e dello script PHP associato.
{
"name": "acme/progetto-esempio",
"description": "Esempio di script Composer per preparare l´ambiente del progetto",
"type": "project",
"require": {
"php": "^8.1"
},
"autoload": {
"psr-4": {
"AcmeApp": "src/"
}
},
"scripts": {
"post-install-cmd": [
"AcmeAppSetupProjectSetup::run"
],
"post-update-cmd": [
"AcmeAppSetupProjectSetup::run"
]
}
}
Ora il file PHP che contiene la logica dello script.
<?php
declare(strict_types=1);
namespace AcmeAppSetup;
final class ProjectSetup
{
public static function run(): int
{
$baseDir = dirname(__DIR__, 2);
$varDir = $baseDir . ´/var´;
$logDir = $varDir . ´/log´;
$cacheDir = $varDir . ´/cache´;
$envFile = $baseDir . ´/.env.local´;
self::ensureDirectory($varDir);
self::ensureDirectory($logDir);
self::ensureDirectory($cacheDir);
if (!file_exists($envFile)) {
$content = <<<ENV
APP_ENV=dev
APP_DEBUG=1
DB_HOST=127.0.0.1
DB_NAME=app
DB_USER=root
DB_PASS=
ENV;
file_put_contents($envFile, $content . PHP_EOL);
echo "[OK] Creato file .env.localn";
} else {
echo "[INFO] File .env.local già presenten";
}
echo "[OK] Ambiente progetto preparato correttamenten";
return 0;
}
private static function ensureDirectory(string $path): void
{
if (!is_dir($path)) {
mkdir($path, 0775, true);
echo "[OK] Creata directory: {$path}n";
} else {
echo "[INFO] Directory già presente: {$path}n";
}
}
}
Per far funzionare il tutto, il file deve trovarsi in una posizione coerente con l’autoload PSR-4. Per esempio:
src/Setup/ProjectSetup.php Inoltre, la struttura del progetto potrebbe essere questa:
progetto-esempio/
├── composer.json
├── src/
│ └── Setup/
│ └── ProjectSetup.php
└── var/
Dopo aver configurato tutto, basta eseguire:
composer install oppure:
composer update e Composer lancerà automaticamente lo script definito negli eventi post-install-cmd e post-update-cmd.
Spiegazione
Vediamo con calma come funziona il meccanismo.
1. Cosa sono gli script di Composer
Gli script sono azioni automatiche eseguite da Composer in risposta a determinati eventi. Nel nostro caso usiamo due eventi molto comuni:
- post-install-cmd: viene eseguito dopo composer install;
- post-update-cmd: viene eseguito dopo composer update.
Questo significa che la preparazione iniziale del progetto non dipende dalla memoria dello sviluppatore: viene eseguita sempre, in modo coerente.
2. Perché usare una classe PHP invece di un comando shell
Composer permette di lanciare sia comandi shell sia metodi PHP. In questo esempio abbiamo scelto una classe PHP perché è più portabile e più facile da testare. Inoltre:
- funziona allo stesso modo su Linux, macOS e Windows;
- puoi usare logica condizionale più ricca;
- hai un controllo migliore sugli errori;
- il codice resta nel progetto, quindi è versionato insieme al resto.
3. Il ruolo dell’autoload
La classe AcmeAppSetupProjectSetup viene caricata grazie alla sezione autoload del file composer.json. Senza questa configurazione, Composer non saprebbe dove trovare la classe.
Il mapping PSR-4 dice che il namespace AcmeApp corrisponde alla cartella src/. Quindi:
- AcmeAppSetupProjectSetup → src/Setup/ProjectSetup.php
4. Come funziona il metodo run()
Il metodo run() contiene la logica principale:
- calcola la directory base del progetto;
- verifica se esistono le cartelle necessarie;
- le crea se mancano;
- controlla la presenza del file .env.local;
- lo genera con valori di base se non esiste.
Questo è un esempio semplice, ma già molto utile in un progetto reale. L’obiettivo non è fare tutto automaticamente a ogni costo, ma ridurre le operazioni manuali ripetitive e soggette a dimenticanze.
5. Perché restituire 0
Il metodo restituisce 0 per indicare che l’operazione è andata a buon fine. In ambiente CLI è una convenzione importante: un codice di uscita pari a zero segnala successo, mentre un valore diverso da zero indica errore.
Best practice
Gli script di Composer sono potenti, ma vanno usati con criterio. Ecco alcune buone pratiche da seguire.
- Evita logiche troppo complesse: gli script devono semplificare il setup, non sostituire un sistema di deploy completo.
- Rendi gli script idempotenti: se vengono eseguiti più volte, non devono rompere il progetto né duplicare dati.
- Usa messaggi chiari: stampa sempre informazioni comprensibili su ciò che sta succedendo.
- Non sovrascrivere file importanti senza controllo: nel nostro esempio il file .env.local viene creato solo se manca.
- Separare il codice degli script: evita di scrivere tutto direttamente nel composer.json; meglio usare classi dedicate.
- Testa il comportamento su installazione pulita: è il modo migliore per scoprire dipendenze nascoste o assunzioni sbagliate.
Un altro consiglio utile: se lo script diventa troppo grande, valuta di trasformarlo in un comando CLI dedicato o in un piccolo task runner interno al progetto. Composer è ottimo per l’automazione leggera, ma non deve diventare un contenitore per tutta la logica operativa.
Riepilogo
Gli script di Composer sono una funzionalità pratica per automatizzare attività ripetitive legate alla vita del progetto. In questo tutorial abbiamo visto come usarli per preparare automaticamente l’ambiente dopo installazione o aggiornamento, creando directory e file di configurazione in modo sicuro e coerente.
I punti chiave da ricordare sono:
- Composer può eseguire script in risposta a eventi specifici;
- post-install-cmd e post-update-cmd sono eventi molto utili;
- una classe PHP dedicata rende lo script più ordinato e portabile;
- gli script devono essere semplici, idempotenti e ben documentati;
- questa tecnica migliora la qualità del setup iniziale e riduce gli errori manuali.
Se usato bene, Composer non serve solo a installare librerie: può diventare un alleato concreto per standardizzare il workflow del team e rendere il progetto più professionale.
Approfondisci con risorse ufficiali
Per andare oltre e conoscere tutti i dettagli, ti consiglio di consultare la documentazione ufficiale di Composer:
- Composer Scripts: documentazione sugli script e sugli eventi supportati;
- Composer Autoloading: per capire come collegare classi e namespace;
- Composer Schema: per esplorare tutte le opzioni disponibili nel file composer.json;
- Composer Command Line: per approfondire i comandi install, update e dump-autoload.
Studiare la documentazione ufficiale è il modo migliore per usare Composer in modo corretto e sfruttarne davvero tutto il potenziale nei progetti PHP moderni.
