我们本日就带来几种PHP自身的办法实现的异步操作。
fsockopen
实验代码
ceshi.php
<?php// 我本地用的docker环境,web为我的容器名称,可以根据自己的环境修正 如:localhost$fd = fsockopen('web', '80');if (!$fd) { echo "fsockopen error";} else { stream_set_blocking($fd, true); // 设置 $fd 为非壅塞模式 $out = "GET /b.php HTTP/1.1\r\n"; $out .= "Host: web\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fd, $out); $start_time = time(); fgets($fd, 128); $end_time = time(); echo "fsockopen非壅塞模式实行韶光:". ($end_time - $start_time); fclose($fd);}
b.php
<?phpsleep(2); echo "b.php";
实行结果
壅塞模式调度为壅塞、非壅塞结果分别如下:
壅塞模式下结果
非壅塞墨水下结果
stream_set_blocking 影响的是 fgets 那一步的操作。
从上面两个图可以得出结果:fsockopen 支持异步
pcntl
实行系统调用,fork出一个子进程异步处理任务,此模式只适用于cli模式下。
测试代码
<?php$id = pcntl_fork();if ($id == -1) { die('could not fork');} else if($id == 0) { echo "子进程处理\r\n";} else { echo "父进程处理\r\n"; pcntl_wait($status);}
实行结果
pcntl实行结果
此模式下是创建一个子进程去处理任务。pcntl_wait 等待子进程结束。
pcntl 支持异步
curl
有人说 curl 也是支持异步实行,查阅了一下资料,网上貌似确实有人证明了异步的结果。本人自己在本地实验了一把,刚开始得到的结论确实是支持异步的,仔细剖析之下,创造对方的 curl_exec 实行的过程中发生 400缺点,以是才造成异步实行的表象。
下面是我自己证明不是异步实行的实验。
实验代码
ceshi.php
<?php// 我本地用的docker环境,web为我的容器名称,可以根据自己的环境修正 如:localhost$ch = curl_init("http://web/b.php");$ch_arr = array(CURLOPT_TIMEOUT=>5,CURLOPT_RETURNTRANSFER=>1);//5秒超时限定?curl_setopt_array($ch,$ch_arr);$start_time = time();$re = curl_exec($ch);curl_close($ch);$end_time = time();echo "CURL实行韶光: ". ($end_time - $start_time);echo "<br> b.php 内容: {$re} <br>";echo "ceshi.php";
b.php
<?phpsleep(2);echo "b.php";
实行结果
curl远程调用结果
结合代码和截图,我们创造 CURL 实行韶光刚好是 b.php 程序 sleep 的韶光。以是curl调用为同步操作。
结论
fsockopen 支持异步。
pcntl 支持异步,但是只适用于 cli 运行模式下。
curl 不支持异步。