小编给大家分享一下PHP怎样实现异步,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
三种实现方式
通用的异步执行文件 exec.php
sleep(8);
$data = "--- type " . date("Y-m-d H:i:s") . " ---\\n";
file_put_contents("../log.txt", $data, FILE_APPEND);
popen
通过 popen() 函数打开进程文件指针,从而能异步执行脚本文件。(只在linux下有效)
pclose(popen("php exec.php &", 'r'));
echo 1;
缺点:只能异步执行本地的脚本文件,不能跨域执行,不能传递参数。
每次执行都会创建新的进程,当并发量高时就创建大量进程,从而造成资源浪费。
curl
应用程序以 curl 发起 http 请求的形式实现异步。但是 curl 请求也需要等待请求返回,程序同样会阻塞,这时我们需要设置 http 请求的超时时间为1s,这样相当于发起了一个 http 请求去执行任务,但是不等待其返回结果,继续向下执行程序,这样就可以实现异步效果。
function asyncCurl($url, $data)
{
if (is_array($data)) {
$data = http_build_query($data, null, '&');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result['response'] = curl_exec($ch);
$result['httpCode'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
return $result;
}
$url = "<http://127.0.0.1/exec.php>";
$data = [];
asyncCurl($url, $data);
echo "OK";
curl 请求实现异步方式的缺陷就是 http 请求的最小超时时间为1s。也就是应用程序无论如何都要等待1s钟以上才能响应(现在 curl 扩展也能支持毫秒级别的超时时间设置,不过毫秒时间的超时很容易造成请求失败)。
fsockopen
fsockopen() 函数用于打开一个网络连接或者一个Unix套接字连接。通过发起 http 通信来实现异步。
从原理上来说与 curl 请求一样。
function sockPost($host, $url, $param)
{
$port = parse_url($url, PHP_URL_PORT);
$port = $port ? $port : 80;
$scheme = parse_url($url, PHP_URL_SCHEME);
$path = parse_url($url, PHP_URL_PATH);
$query = http_build_query($param);
if ($scheme == 'https') {
$host = 'ssl://' . $host;
}
$fp = fsockopen($host, $port, $error_code, $error_msg, 1);
if (!$fp) {
return array('error_code' => $error_code, 'error_msg' => $error_msg);
} else {
stream_set_blocking($fp, 0);
stream_set_timeout($fp, 10);
$header = "GET $path" . "?" . "$query" . " HTTP/1.1\\r\\n";
$header .= "Host: $host\\r\\n";
$header .= "Connection: close\\r\\n\\r\\n";//长连接关闭
fwrite($fp, $header);
usleep(2000); // 延时,防止在nginx服务器上无法执行成功
fclose($fp);
return array('error_code' => 0);
}
}
$host = "127.0.0.1";
$url = "/exec.php";
$param = [];
$result = sockPost($host, $url, $param);
var_dump($result);
fsockopen 方式相比 curl 更复杂,需要自己拼接处 http 请求的 header 部分。在 curl 不支持毫秒级超时之前 fsockopen 方式无疑是最佳选择。
以上是“PHP怎样实现异步”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。