Hai un loop di 10 chiamate API che impiegano 3 secondi l'una? In PHP classico aspetti 30 secondi. Con i Fibers di PHP 8.1 puoi eseguirle in solo 3 secondi — e senza installare un framework. Sembra magia, ma è solo programmazione asincrona fatta con le funzionalità native del linguaggio.
Noi di Meteora Web sviluppiamo in PHP da anni, su piattaforme custom e WordPress. I Fibers sono una di quelle feature che cambiano il modo di pensare: ti permettono di scrivere codice asincrono senza dover adottare ReactPHP, Amp, o altri ecosistemi. In questa guida ti spieghiamo come funzionano e come usarli subito, con esempi pronti all'uso.
Cosa sono i Fibers e perché sono utili in PHP 8.1?
Un Fiber è un'unità di esecuzione cooperativa che può sospendersi e riprendere da dove era stata interrotta. A differenza dei thread, i Fiber condividono lo stesso processo e la stessa memoria: non c'è parallelismo reale, ma una concorrenza sincrona controllata dal programmatore.
Il vantaggio è immediato: mentre aspetti una risposta da un database o da un'API, invece di bloccare l'intero script, sospendi il Fiber e lasci eseguire altro codice. Appena la risposta arriva, riprendi il Fiber da dove si era fermato.
Prima di PHP 8.1, per ottenere un comportamento simile dovevi usare generatori (yield) o librerie esterne. I Fiber offrono un'API più pulita e flessibile, con piena gestione degli stack di chiamate e delle eccezioni.
La differenza tra Fiber, Generator e Thread
Mettiamola così:
- Generator: può sospendere e restituire un valore, ma non può essere ripreso dall'esterno se non iterando. Non può ricevere dati al momento della ripresa.
- Thread (tramite
pthreadsoparallel): esegue codice in parallelo reale su più core, ma è pesante, complesso e non supportato su server condivisi. - Fiber: si sospende e viene ripreso da un altro punto del codice, con scambio bidirezionale di dati. Usa un unico thread, quindi è leggero e sicuro per operazioni I/O-bound.
Per le PMI che gestiscono siti con molte richieste esterne (es. e-commerce che interroga più fornitori), i Fiber sono la soluzione giusta: nessuna dipendenza, overhead minimo, performance moltiplicate.
Sponsored Protocol
Come funzionano i Fibers rispetto alle coroutine tradizionali?
Un Fiber si crea con new Fiber(callback). La callback contiene il codice che verrà eseguito. Per avviarlo, chiami $fiber->start(). All'interno della callback, chiami Fiber::suspend($valore) per sospendere il Fiber e restituire un valore al chiamante. Da fuori, chiami $fiber->resume($dato) per riprendere l'esecuzione passando un valore di ritorno al punto di sospensione.
La differenza chiave rispetto a generatori e coroutine classiche: lo stack di chiamate viene preservato. Se all'interno del Fiber hai funzioni annidate, una eccezione emessa in profondità può essere catturata dal chiamante senza problemi. Con i generatori dovevi gestire manualmente la propagazione.
$fiber = new Fiber(function (): void {
echo "Inizio Fiber\n";
$val = Fiber::suspend('primo stop');
echo "Ripreso con: $val\n";
});
$risultato = $fiber->start();
echo $risultato; // 'primo stop'
$fiber->resume('ciao'); // stampa "Ripreso con: ciao"
Attenzione: il Fiber non lancia codice in background. È un costrutto di controllo di flusso. Il vero potere arriva quando lo combini con uno scheduler che decide quali Fiber attivare in base a eventi asincroni (es. socket non bloccanti, timer). Ma anche senza scheduler, puoi già usare i Fiber per scrivere codice più leggibile che altrimenti sarebbe un groviglio di callback.
Sponsored Protocol
Come implementare un semplice scheduler asincrono con i Fibers?
Uno scheduler è il cuore della programmazione asincrona. Gestisce una coda di Fiber attivi e li riprende quando un evento si verifica. Ecco un esempio minimale per eseguire più task che simulano operazioni di I/O (attese di durata variabile).
class SimpleScheduler {
private array $tasks = [];
public function add(callable $task): void {
$this->tasks[] = new Fiber($task);
}
public function run(): void {
while (!empty($this->tasks)) {
foreach ($this->tasks as $key => $fiber) {
if ($fiber->isStarted() === false) {
$fiber->start();
} elseif ($fiber->isTerminated() === false) {
$fiber->resume();
} else {
unset($this->tasks[$key]);
}
}
}
}
}
$scheduler = new SimpleScheduler();
$scheduler->add(function () {
echo "Inizio task 1\n";
Fiber::suspend();
echo "Fine task 1\n";
});
$scheduler->add(function () {
echo "Inizio task 2\n";
Fiber::suspend();
echo "Fine task 2\n";
});
$scheduler->run();
// Output: Inizio task 1, Inizio task 2, Fine task 1, Fine task 2
Ovviamente questo è uno scheduler banale (round-robin senza priorità). In uno scenario reale vorresti riprendere i Fiber solo quando il dato è pronto (es. usando stream_select o curl_multi_select). Tuttavia dimostra il principio: più task progrediscono senza attendere il completamento dell'altro.
Sponsored Protocol
Esempio pratico: scaricare più URL in parallelo
Con un vero scheduler basato su curl_multi e Fiber potresti scrivere:
function fetchUrlAsync(string $url): string {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
// ... configurazione curl_multi ...
// Sospendi il Fiber fino a che la risposta è pronta
$data = Fiber::suspend($ch);
return $data;
}
// Uso
$fiber = new Fiber(function () {
$result = fetchUrlAsync('https://api.example.com/data');
echo $result;
});
$fiber->start();
// ... gestione dell'event loop che riprende quando curl completa
Esistono librerie minimali (es. Revolt) che forniscono un event loop già pronto, ma se vuoi restare completamente senza framework puoi implementare da zero poche centinaia di righe. Noi di Meteora Web preferiamo spesso integrare Revolt perché è leggero e non impone un framework full-stack.
Sponsored Protocol
Quali sono i limiti dei Fibers e quando usarli (o evitarli)?
I Fiber non sono una bacchetta magica. Ecco i punti da conoscere prima di usarli in produzione:
- Nessun parallelismo CPU-bound: se il tuo codice fa calcoli intensivi, i Fiber non velocizzeranno nulla. Per quello servono estensioni come
parallelo processi separati. - Richiedono un event loop per I/O asincrono: i Fiber da soli non fanno magicamente diventare non bloccanti le funzioni di I/O (file, database, socket). Devi usare versioni non bloccanti o wrapper come
ext-uv,ext-evo librerie che le espongono. - Overhead dello scheduler: se gestisci centinaia di Fiber, lo scheduler diventa critico per le performance.
- Compatibilità con codice legacy: funzioni che usano
sleep(),file_get_contents()bloccante, o estensioni non progettate per async rompono il modello. Devi sostituirle.
Dove brillano? Operazioni I/O-bound parallele: chiamate API, query multiple a database, scraping, elaborazione di file remoti. Se hai un'applicazione che fa molte richieste HTTP, i Fiber possono ridurre i tempi di risposta da minuti a secondi.
Come integrare Fibers in un progetto PHP esistente senza framework?
Se hai un'applicazione sviluppata senza framework (o con framework leggero), puoi introdurre i Fiber gradualmente:
- Identifica i colli di bottiglia: operazioni sequenziali di rete o I/O.
- Riscrivi quelle funzioni per usare
Fiber::suspend()e un mini-scheduler. - Assicurati che tutte le funzioni chiamate all'interno del Fiber siano non bloccanti (o usa wrapper come
curl_multi). - Testa con attenzione: le eccezioni non gestite all'interno di un Fiber possono essere complicate da debuggare.
Un pattern comune è creare un FiberPool che gestisce un numero fisso di Fiber concorrenti, limitando il carico. Noi lo abbiamo usato per parallelizzare l'invio di email transazionali e per aggregare dati da più marketplace in un unico pannello.
Sponsored Protocol
Checklist per l'adozione
- PHP 8.1 o superiore
- Event loop (Revolt, Amp, o custom)
- Estensioni per I/O non bloccante (curl_multi, sockets, ext-uv opzionale)
- Gestione centralizzata delle eccezioni nei Fiber
- Monitoraggio del consumo di memoria (ogni Fiber mantiene tutto lo stack)
Cosa fare adesso
Non aspettare il framework perfetto. I Fiber sono già nel tuo PHP. Ecco tre azioni concrete per iniziare oggi:
- Apri un terminale e testa l'esempio con
php -r '...'(usa il codice dello scheduler semplice sopra). - Identifica un'attività ripetitiva nel tuo progetto (es. polling di 3 API ogni minuto) e prova a riscriverla con i Fiber.
- Leggi la documentazione ufficiale sui Fiber: PHP Manual – Fibers.
Noi di Meteora Web usiamo i Fiber nei nostri progetti Laravel/Livewire per gestire code di operazioni asincrone leggere, ma li abbiamo anche introdotti in siti WordPress plugin per la sincronizzazione di prodotti con warehouse esterne. Se vuoi approfondire,l'intero ecosistema PHP 8 avanzato è esplorato nel nostro Pillar su PHP 8 Avanzato.