How can one use multi threading in PHP applications
Multi-threading is possible in php
Yes you can do multi-threading in PHP with pthreads
From the PHP documentation:
pthreads is an object-orientated API that provides all of the tools needed for multi-threading in PHP. PHP applications can create, read, write, execute and synchronize with Threads, Workers and Threaded objects.
Warning: The pthreads extension cannot be used in a web server environment. Threading in PHP should therefore remain to CLI-based applications only.
Simple Test
#!/usr/bin/php<?phpclass AsyncOperation extends Thread { public function __construct($arg) { $this->arg = $arg; } public function run() { if ($this->arg) { $sleep = mt_rand(1, 10); printf('%s: %s -start -sleeps %d' . "\n", date("g:i:sa"), $this->arg, $sleep); sleep($sleep); printf('%s: %s -finish' . "\n", date("g:i:sa"), $this->arg); } }}// Create a array$stack = array();//Initiate Multiple Threadforeach ( range("A", "D") as $i ) { $stack[] = new AsyncOperation($i);}// Start The Threadsforeach ( $stack as $t ) { $t->start();}?>
First Run
12:00:06pm: A -start -sleeps 512:00:06pm: B -start -sleeps 312:00:06pm: C -start -sleeps 1012:00:06pm: D -start -sleeps 212:00:08pm: D -finish12:00:09pm: B -finish12:00:11pm: A -finish12:00:16pm: C -finish
Second Run
12:01:36pm: A -start -sleeps 612:01:36pm: B -start -sleeps 112:01:36pm: C -start -sleeps 212:01:36pm: D -start -sleeps 112:01:37pm: B -finish12:01:37pm: D -finish12:01:38pm: C -finish12:01:42pm: A -finish
Real World Example
error_reporting(E_ALL);class AsyncWebRequest extends Thread { public $url; public $data; public function __construct($url) { $this->url = $url; } public function run() { if (($url = $this->url)) { /* * If a large amount of data is being requested, you might want to * fsockopen and read using usleep in between reads */ $this->data = file_get_contents($url); } else printf("Thread #%lu was not provided a URL\n", $this->getThreadId()); }}$t = microtime(true);$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));/* starting synchronization */if ($g->start()) { printf("Request took %f seconds to start ", microtime(true) - $t); while ( $g->isRunning() ) { echo "."; usleep(100); } if ($g->join()) { printf(" and %f seconds to finish receiving %d bytes\n", microtime(true) - $t, strlen($g->data)); } else printf(" and %f seconds to finish, request failed\n", microtime(true) - $t);}
why don't you use popen?
for ($i=0; $i<10; $i++) { // open ten processes for ($j=0; $j<10; $j++) { $pipe[$j] = popen('script2.php', 'w'); } // wait for them to finish for ($j=0; $j<10; ++$j) { pclose($pipe[$j]); }}
Threading isn't available in stock PHP, but concurrent programming is possible by using HTTP requests as asynchronous calls.
With the curl's timeout setting set to 1 and using the same session_id for the processes you want to be associated with each other, you can communicate with session variables as in my example below. With this method you can even close your browser and the concurrent process still exists on the server.
Don't forget to verify the correct session ID like this:
http://localhost/test/verifysession.php?sessionid=[the correct id]
startprocess.php
$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $request);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_TIMEOUT, 1);curl_exec($ch);curl_close($ch);echo $_REQUEST["PHPSESSID"];
process1.php
set_time_limit(0);if ($_REQUEST["sessionid"]) session_id($_REQUEST["sessionid"]);function checkclose(){ global $_SESSION; if ($_SESSION["closesession"]) { unset($_SESSION["closesession"]); die(); }}while(!$close){ session_start(); $_SESSION["test"] = rand(); checkclose(); session_write_close(); sleep(5);}
verifysession.php
if ($_REQUEST["sessionid"]) session_id($_REQUEST["sessionid"]);session_start();var_dump($_SESSION);
closeprocess.php
if ($_REQUEST["sessionid"]) session_id($_REQUEST["sessionid"]);session_start();$_SESSION["closesession"] = true;var_dump($_SESSION);