Concurrency and Multithreading in PHP: A Practical Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why PHP Needs Concurrency

PHP is traditionally considered a synchronous language, where each request is processed sequentially. However, modern web applications require performing many tasks simultaneously: queue processing, working with APIs, image processing, data parsing. Concurrency and multithreading in PHP allow solving these problems, increasing application performance and responsiveness.

In this article, we will analyze the main approaches: multithreading via pthreads, parallel processes via pcntl_fork, asynchronous programming using ReactPHP, and modern Fibers in PHP 8.1+. Each method has its own strengths and limitations, which we will examine with practical examples.



Approach 1: Multithreading with the pthreads Extension

pthreads is an extension for working with threads in PHP. It is only available for the CLI version and requires compilation with the --enable-maintainer-zts flag. Threads share memory, which allows efficient data exchange but requires caution with locks.

Installation and Configuration

# Installation via peclpecl install pthreads

# Check in php.iniextension=pthreads.so

Example: Parallel Array Processing

<?phpclass WorkerThread extends Thread {    private $data;    private $result;

public function __construct($data) { $this->data = $data; }

public function run() { // Simulating a heavy operation $this->result = array_map(function($item) { sleep(1); // 1 second per item return $item * 2; }, $this->data); }

public function getResult() { return $this->result; }}

// Create 5 threads$threads = [];$dataChunks = array_chunk(range(1, 100), 20);

foreach ($dataChunks as $chunk) { $thread = new WorkerThread($chunk); $thread->start(); $threads[] = $thread;}

// Collecting results$finalResult = [];foreach ($threads as $thread) { $thread->join(); $finalResult = array_merge($finalResult, $thread->getResult());}

echo "Processed " . count($finalResult) . " items in ~5 seconds instead of 100.";

Important: pthreads does not work in a web environment (Apache/Nginx + mod_php). Use only for CLI scripts, workers, and daemons.



Approach 2: Parallel Processes via pcntl_fork

The pcntl_fork() function creates a child process by copying the current script. Processes are isolated in memory, which is safer than threads, but inter-process communication (IPC) requires additional mechanisms: message queues, shared memory, or sockets.

Example: Parallel URL Downloading

<?php$urls = [    'https://api.example.com/data1',    'https://api.example.com/data2',    'https://api.example.com/data3',];

$pids = [];foreach ($urls as $url) { $pid = pcntl_fork(); if ($pid == -1) { die("Fork error"); } elseif ($pid == 0) { // Child process $content = file_get_contents($url); file_put_contents('/tmp/' . md5($url) . '.json', $content); exit(0); // Important to terminate the child process } else { $pids[] = $pid; }}

// Wait for all child processes to finishforeach ($pids as $pid) { pcntl_waitpid($pid, $status);}

echo "All URLs downloaded in parallel.";

Limitations:

  • Does not work with a web server (CLI only).
  • Each process consumes the parent's memory.
  • Difficult to synchronize access to shared resources.


Approach 3: Asynchrony with ReactPHP

ReactPHP is a library for event-driven programming

Blogs

Book Recommendations