09 11 2019

最近一个小项目碰上需要异步执行PHP代码的情况。

原生PHP并没有异步执行的功能,只能一步一步的顺序执行。

初步解决思路:(为了方便命名a.php和b.php两个文件)

1、a.php去除需要异步执行的代码,将需要异步执行的代码放在b.php文件中,使得a.php执行时间大大缩短,然后在a.php里面通过js加载b.php来间接实现代码的异步执行。

2、a.php去除需要异步执行的代码,将需要异步执行的代码放在b.php文件中,通过curl设置超时时间,a.php中通过curl设置超时20ms,然后curl b.php文件,触发b.php文件的代码执行。

综合考虑网络等各种影响因素,js加载b.php不如a.php中curl触发b.php代码来的高效。

下面是a.php代码,实验得出超时时间20ms是比较适合的,少于20ms可能会还没有触发b.php就退出了。

<?php
$oCurl = curl_init();
curl_setopt($oCurl, CURLOPT_URL, 'http://你的ip/b.php');
curl_setopt($oCurl, CURLOPT_NOBODY, true);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST, false);
curl_setopt($oCurl, CURLOPT_NOSIGNAL, true); //注意,毫秒超时一定要设置这个  
curl_setopt($oCurl, CURLOPT_TIMEOUT_MS, 20);
$sContent = curl_exec($oCurl);
curl_close($oCurl);

接下来是b.php的代码:

<?php
error_reporting(0);
ignore_user_abort(true);
sleep(3);
file_put_contents('./d.txt','1');

b.php代码中ignore_user_abort(true)是关键,可以允许php在断开连接后继续执行命令。


通过上面代码就可以实现,访问a.php,很快速的就结束了访问,但是后台3秒后b.php代码才会执行完成写入一个d.txt文件。


php异步执行的功能有很多应用场景,例如 随机图片api,通过访客调用随机图片,可以在后台触发图片采集进程。


辣么问题来了,有童鞋可能会说,那为啥子不让一个php进程直接常驻后台,而通过异步触发来执行,

php常驻后台有几个坏处,一个是进程的不可控,php离线不计超时的运行,无法控制运行进程,且会长时间占用内存和CPU。


目前这种php异步代码博主已经在多个项目中测试使用,效果非常显著,特别是需要采集数据的进程中,异步处理可以很好的解决数据更新时前台打开的卡顿问题。

  1. 上一篇:SEO基础教程一
  2. 下一篇:PHP教程之三目运算
发表评论