Introducción: ¿por qué un desarrollador PHP debería pensar en concurrencia?
\n\nHubo un tiempo en que se creía que PHP era un lenguaje para "scripts rápidos", donde todo se ejecutaba de forma secuencial y no se necesitaba ningún trabajo paralelo serio. Los tiempos han cambiado. Hoy construimos con PHP APIs de alta carga, colas de tareas, websockets e incluso microservicios. Y entonces surge la pregunta: ¿cómo hacer que PHP realice varias tareas simultáneamente sin bloquear todo?
\n\nEn este artículo analizaremos tres enfoques para la concurrencia en PHP: los hilos clásicos (pthreads), las gorutinas ligeras (Fiber) y la sintaxis moderna async/await. Verás ejemplos de código reales, aprenderás cuándo usar cada herramienta y qué deberías elegir en 2025.
\n\nSi buscas ejecución paralela en PHP para procesar datos, o quieres entender cómo se diferencian las gorutinas PHP de los hilos, has llegado al lugar indicado.
\n\n1. Multihilo en PHP: pthreads — el viejo pero poderoso
\n\n¿Qué es y cómo funciona?
\npthreads es una extensión que le da a PHP la capacidad de crear hilos reales del sistema operativo. Cada hilo es una instancia independiente del motor Zend con su propia memoria, pero con la posibilidad de intercambiar datos a través de objetos Threaded.
Un detalle importante: pthreads solo funciona en modo CLI y no es compatible con entornos web (Apache/Nginx mod_php). Sin embargo, es la única forma de obtener paralelismo real (no solo concurrencia) a nivel de CPU.
\n\nEjemplo: parseo paralelo de URLs
\n<?php\n// Asegúrate de tener instalada la extensión pthreads\nclass UrlFetcher extends Thread {\n private $url;\n private $result;\n\n public function __construct(string $url) {\n $this->url = $url;\n }\n\n public function run() {\n // Se ejecuta en un hilo separado\n $this->result = file_get_contents($this->url);\n }\n\n public function getResult() {\n return $this->result;\n }\n}\n\n$urls = ['https://api.example.com/1', 'https://api.example.com/2', 'https://api.example.com/3'];\n$threads = [];\n\nforeach ($urls as $url) {\n $thread = new UrlFetcher($url);\n $thread->start(); // Iniciamos el hilo\n $threads[] = $thread;\n}\n\n// Recogemos los resultados\nforeach ($threads as $thread) {\n $thread->join(); // Esperamos a que termine\n echo $thread->getResult() . PHP_EOL;\n}\n?>\n\nEl código lanza tres hilos, cada uno descarga su propia URL. El tiempo de ejecución es aproximadamente igual al de la solicitud más lenta, no la suma de las tres. Una excelente ilustración de la ejecución paralela en PHP.
\n\n¿Cuándo usar pthreads?
\n- \n
- Tareas pesadas de CPU (procesamiento de imágenes, cifrado, renderizado de PDF). \n
- Parseo de grandes volúmenes de datos en scripts CLI. \n
- Cuando necesitas paralelismo real, no multitarea cooperativa. \n
2. Gorutinas en PHP: Fiber — ligereza y control
\n\n¿Qué es Fiber?
\nA partir de PHP 8.1, el lenguaje incorporó Fiber, un equivalente de las gorutinas de Go o las corrutinas de Python. A diferencia de los hilos, Fiber no crea un proceso separado del sistema operativo. Es una unidad de ejecución ligera que trabaja en un solo hilo y se cambia bajo demanda del desarrollador.
\n\nLa idea clave: tú decides cuándo pausar el Fiber actual y ceder el control a otro. Esto se llama multitarea cooperativa. Ideal para operaciones de E/S (solicitudes a APIs, lectura de archivos, trabajo con bases de datos).
\n\nEjemplo: recorrido asíncrono de directorios
\n<?php\nfunction readFileAsync(string $path): Fiber {\n return new Fiber(function () use ($path) {\n $handle = fopen($path, 'r');\n $content = '';\n while (!feof($handle)) {\n $chunk = fread($handle, 4096);\n $content .= $chunk;\n // Pausamos el Fiber para dar oportunidad a otros\n