我们本日就带来几种PHP自身的办法实现的异步操作。

fsockopen

实验代码

ceshi.php

phprPHP实现异步骤用的方法 Bootstrap

<?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 不支持异步。