Las Fibers de PHP 8.1 son rutinas ligeras que permiten pausar la ejecución de una función y reanudarla más tarde desde el mismo punto, sin usar hilos del sistema operativo. Son el bloque de construcción de las librerías de concurrencia cooperativa como Revolt y Amp, que las usan internamente para implementar async/await.
Conceptos básicos: crear, iniciar, pausar y reanudar
<?php
$fiber = new Fiber(function (): void {
echo "Fiber: antes de suspendn";
$valor = Fiber::suspend('primer yield');
echo "Fiber: recibí '$valor' tras el primer suspendn";
Fiber::suspend('segundo yield');
echo "Fiber: terminandon";
});
$resultado1 = $fiber->start(); // inicia la fiber
echo "Main: fiber devolvió '$resultado1'n"; // primer yield
$resultado2 = $fiber->resume('hola'); // reanuda, pasando 'hola' como valor
echo "Main: fiber devolvió '$resultado2'n"; // segundo yield
$fiber->resume(); // reanuda por última vez, la fiber termina
?>
Salida:
Fiber: antes de suspend Main: fiber devolvió 'primer yield' Fiber: recibí 'hola' tras el primer suspend Main: fiber devolvió 'segundo yield' Fiber: terminando
Estado de una Fiber
<?php
$fiber = new Fiber(function (): string {
Fiber::suspend();
return 'resultado final';
});
var_dump($fiber->isStarted()); // false
var_dump($fiber->isSuspended()); // false
$fiber->start();
var_dump($fiber->isStarted()); // true
var_dump($fiber->isSuspended()); // true
var_dump($fiber->isRunning()); // false
var_dump($fiber->isTerminated()); // false
$fiber->resume();
var_dump($fiber->isTerminated()); // true
echo $fiber->getReturn(); // resultado final
?>
Ejemplo real: leer múltiples ficheros sin bloquear
<?php
function leerFicheroFiber(string $ruta): Fiber
{
return new Fiber(function () use ($ruta): void {
// Simular lectura asíncrona (en producción sería I/O real no bloqueante)
Fiber::suspend("leyendo: $ruta");
$contenido = file_get_contents($ruta);
Fiber::suspend("leído: " . strlen($contenido ?? '') . " bytes de $ruta");
});
}
$fibers = [
leerFicheroFiber('/etc/hostname'),
leerFicheroFiber('/etc/os-release'),
];
// Iniciar todas
foreach ($fibers as $f) {
echo $f->start() . "n";
}
// Reanudar todas
foreach ($fibers as $f) {
echo $f->resume() . "n";
}
?>
Cómo Revolt usa las Fibers internamente
Revolt es el loop de eventos que usa Amp v3. Su modelo es: cada operación await suspende la Fiber actual y cede el control al loop, que ejecuta otras Fibers hasta que la operación de I/O completa y la reanuda:
<?php
// Ejemplo conceptual (requiere revolt/event-loop)
// composer require revolt/event-loop
use RevoltEventLoop;
EventLoop::queue(function (): void {
$fiber = new Fiber(function (): void {
echo "Tarea A: inicion";
Fiber::suspend();
echo "Tarea A: finn";
});
$fiber->start();
echo "Tarea B: ejecutándose mientras A está suspendidan";
$fiber->resume();
});
EventLoop::run();
// Tarea A: inicio
// Tarea B: ejecutándose mientras A está suspendida
// Tarea A: fin
?>
Diferencias con generators
Característica | Generator | Fiber |
Puede estar en la pila de llamadas | No | Sí |
Suspensión desde funciones anidadas | No | Sí |
Puede pasar valor al reanudar | Sí (send) | Sí (resume) |
Uso principal | Iteración lazy | Concurrencia cooperativa |
La documentación oficial de Fiber en PHP describe la API completa de la clase, los estados posibles y las restricciones de uso (no se puede usar dentro de otra Fiber sin un loop de eventos).
