Introduction: Why Concurrency in PHP Is Not a Myth
\nPHP is traditionally considered a synchronous language, where each request is processed sequentially. However, modern applications — from video processing to big data parsing — require executing multiple tasks simultaneously. Without concurrency, you risk hitting a "performance wall," where even a powerful server sits idle waiting for I/O operations to complete.
\nIn this article, we will explore advanced techniques for working with concurrency in PHP: from system calls to kernel-level extensions. You will learn how to make PHP work in parallel without losing control over resources.
\n\n1. Basics: Processes vs Threads in PHP
\nBefore diving into code, it's important to understand the difference between processes and threads in the context of PHP.
\n- \n
- Processes — isolated instances, each with its own memory. Created via
pcntl_fork(). Suitable for heavy tasks but require inter-process communication (IPC). \n - Threads — lightweight "subtasks" within a single process, sharing memory. Implemented via the
pthreadsextension. Ideal for working with shared data but require synchronization. \n
At an advanced level, it's important to be able to combine both approaches. For example, use forks to isolate critical tasks and threads for parallel processing within a single context.
\n\n1.1 Parallel Processes via pcntl_fork()
\nThe system call pcntl_fork() creates a child process that copies the parent's memory. Consider an example of parallel processing of multiple URLs:
<?php\n$urls = ['https://api.example.com/data1', 'https://api.example.com/data2', 'https://api.example.com/data3'];\n$pids = [];\n\nforeach ($urls as $url) {\n $pid = pcntl_fork();\n if ($pid == -1) {\n die('Failed to create process');\n } elseif ($pid) {\n // Parent process: save PID\n $pids[] = $pid;\n } else {\n // Child process: perform download\n $data = file_get_contents($url);\n file_put_contents('/tmp/' . md5($url) . '.json', $data);\n exit(0); // Terminate child process\n }\n}\n\n// Wait for all processes to finish\nforeach ($pids as $pid) {\n pcntl_waitpid($pid, $status);\n}\necho "All URLs processed in parallel!";\n?>\nImportant: after fork(), child processes inherit all open file descriptors and database connections. Close them explicitly in the child process to avoid conflicts.
\n\n2. Asynchronous Tasks with ReactPHP and Amp
\nFor web applications where reactivity is important, use event-loop libraries. ReactPHP and Amp allow you to perform non-blocking operations without creating separate processes.
\n\n2.1 Example with ReactPHP
\nInstall the library via Composer: composer require react/react. Below is an asynchronous HTTP client that sends three requests simultaneously:
<?php\nrequire 'vendor/autoload.php';\n\nuse React\\EventLoop\\Factory;\nuse React\\HttpClient\\Client;\n\n$loop = Factory::create();\n$client = new Client($loop);\n\n$urls = ['http://example.com', 'http://example.org', 'http://example.net'];\n$promises = [];\n\nforeach ($urls as $url) {\n $request = $client->request('GET', $url);\n $request->on('response', function ($response) use ($url) {\n echo "Response from {$url}: " . $response->getCode() . PHP_EOL;\n });\n $request->end();\n}\n\n$loop->run();\n?>\nReactPHP creates a single event loop that handles all requests without blocking. This is ideal for API gateways or microservices where response speed is critical.
\n\n3. Thread Management with pthreads (ZTS Build)
\nThe pthreads extension is the only way to get true multithreading in PHP.
Blogs
Book Recommendations
Read also
How many bytes are in int and long in C++? The standard answers unexpectedly
Generics in PHP: Why They Are Needed and How to Use Them for Beginners
Canary deployments with TypeScript: seamless release without fear of breaking production
Docker and JavaScript: Containerization of Node.js Applications (Advanced Level)
Top 10 Go Frameworks for Web Development in 2025