PHP非阻塞实现方法

转自https://www.awaimai.com/660.html

为让 PHP 在后端处理长时间任务时不阻塞,快速响应页面请求,可以有如下措施:

1 使用 fastcgi_finish_request()
如果 PHP 与 Web 服务器使用了PHP-FPM(FastCGI 进程管理器),那通过fastcgi_finish_request()函数能马上结束会话,而 PHP 线程可以继续在后台运行。

echo "program start...";

file_put_contents('log.txt','start-time:'.date('Y-m-d H:i:s'), FILE_APPEND);

fastcgi_finish_request();sleep(1);

echo 'debug...';
file_put_contents('log.txt', 'start-proceed:'.date('Y-m-d H:i:s'), FILE_APPEND);

sleep(10);

file_put_contents('log.txt', 'end-time:'.date('Y-m-d H:i:s'), FILE_APPEND);

2 使用 fsockopen()
使用fsockopen()打开一个网络连接或者一个Unix套接字连接,再用stream_set_blocking()非阻塞模式请求:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);

if (!$fp) { die('error fsockopen');}// 转换到非阻塞模式

stream_set_blocking($fp, 0);

$http = "GET /save.php  / HTTP/1.1\r\n";

$http .= "Host: www.example.com\r\n";

$http .= "Connection: Close\r\n\r\n";fwrite($fp, $http);fclose($fp);

3 使用 cURL
利用cURL中的curl_multi_*函数发送异步请求

$time = time();// 创建一对cURL资源

$ch1 = curl_init();

$ch2 = curl_init();

$ch3 = curl_init();// 设置URL和相应的选项

curl_setopt($ch1, CURLOPT_URL, "http://test.xtgxiso.cn/sleep1.php");

curl_setopt($ch1, CURLOPT_HEADER, 0);

curl_setopt($ch2, CURLOPT_URL, "http://test.xtgxiso.cn/sleep2.php");

curl_setopt($ch2, CURLOPT_HEADER, 0);

curl_setopt($ch3, CURLOPT_URL, "http://test.xtgxiso.cn/sleep3.php");

curl_setopt($ch3, CURLOPT_HEADER, 0);// 创建批处理cURL句柄

$mh = curl_multi_init();// 增加2个句柄

curl_multi_add_handle($mh,$ch1);

curl_multi_add_handle($mh,$ch2);

curl_multi_add_handle($mh,$ch3);

$running=null;// 执行批处理句柄

do { usleep(10000); curl_multi_exec($mh,$running);} while ($running > 0);// 关闭全部句柄

curl_multi_remove_handle($mh, $ch1);

curl_multi_remove_handle($mh, $ch2);

curl_multi_remove_handle($mh, $ch3);

curl_multi_close($mh);

echo "\n total time : ".(time()-$time)."\n";

5 使用缓存和队列
使用redis等缓存、队列,将数据写入缓存,使用后台计划任务实现数据异步处理。

6 调用系统命令
极端的情况下,可以调用系统命令,可以将数据传给后台任务执行

你可能感兴趣的:(PHP)