详解PHP实现异步调用的4种方法


Posted in PHP onMarch 14, 2016

浏览器和服务器之间是通过 HTTP 协议进行连接通讯的。这是一种基于请求和响应模型的协议。浏览器通过 URL 向服务器发起请求,Web 服务器接收到请求,执行一段程序,然后做出响应,发送相应的html代码给客户端。

这就有了一个问题,Web 服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了。

而有的时候,我们更本不关心这些耗时的脚本的返回结果,但却还要等他执行完返回,才能继续下一步。
那么有没有什么办法,只是简单的触发调用这些耗时的脚本然后就继续下一步,让这些耗时的脚本在服务端慢慢执行?

经过试验,总结出来几种方法,和大家share:

1. 最简单的办法,就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。
这种方法最简单,也最快。服务器端不用做任何的调用。
但是缺点是,一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。
而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。
当然,还可以使用其他的类似原理的方法,比如script标签等等。

2. popen()

resource popen ( string command, string mode );
//打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。

所以可以通过调用它,但忽略它的输出。

pclose(popen("/home/xinchen/backend.php &", 'r'));
这个方法避免了第一个方法的缺点,并且也很快。但是问题是,这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。
并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。

3. 使用CURL
这个方法,设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。 

$ch = curl_init();
   
  $curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php',
                CURLOPT_RETURNTRANSFER, 1,
                CURLOPT_TIMEOUT, 1,);
   
  curl_setopt_array($ch, $curl_opt);
   
  curl_exec($ch);
   
  curl_close($ch);

4. 使用fsockopen
这个方法应该是最完美的,但是缺点是,你需要自己拼出HTTP的header部分。

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
  if (!$fp) {
    echo "$errstr ($errno)<br />\n";
  } else {
    $out = "GET /backend.php / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
   
    fwrite($fp, $out);
    /*忽略执行结果
  while (!feof($fp)) {
  echo fgets($fp, 128);
  }*/
    fclose($fp);
  }

所以,总体来看,最好用,最简单的还是第一种方法。
最完美的应该是最后一种,但是比较复杂。
以上就是4种php实现异步调用的方法,希望对大家的学习有所帮助。

PHP 相关文章推荐
smarty 原来也不过如此~~呵呵
Nov 25 PHP
php 购物车的例子
May 04 PHP
PHP缩略图等比例无损压缩,可填充空白区域补充色
Jun 10 PHP
php中用socket模拟http中post或者get提交数据的示例代码
Aug 08 PHP
php递归函数中使用return的注意事项
Jan 17 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
Nov 14 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
Nov 10 PHP
PHP的mysqli_stat()函数讲解
Jan 23 PHP
实例介绍PHP中zip_open()函数用法
Feb 15 PHP
PHP去除空数组且数组键名重置的讲解
Feb 28 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
Mar 27 PHP
laravel框架创建授权策略实例分析
Nov 22 PHP
ThinkPHP框架安全实现分析
Mar 14 #PHP
php语言的7种基本的排序方法
Dec 28 #PHP
php实现图片上传并利用ImageMagick生成缩略图
Mar 14 #PHP
YII Framework框架教程之国际化实现方法
Mar 14 #PHP
YII Framework框架教程之缓存用法详解
Mar 14 #PHP
YII Framework框架教程之安全方案详解
Mar 14 #PHP
YII Framework框架教程之日志用法详解
Mar 14 #PHP
You might like
php中ob_get_length缓冲与获取缓冲长度实例
2014/11/20 PHP
PHP实现网页内容html标签补全和过滤的方法小结【2种方法】
2017/04/27 PHP
javascript 设置文本框中焦点的位置
2009/11/20 Javascript
关于this和self的使用说明
2010/08/01 Javascript
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
js中巧用cssText属性批量操作样式
2011/03/13 Javascript
jQuery 和 CSS 的文本特效插件集锦
2014/12/12 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
js实现添加删除表格(两种方法)
2017/04/27 Javascript
JavaScript仿微信(电话)联系人列表滑动字母索引实例讲解(推荐)
2017/08/16 Javascript
JS实现闭包中的沙箱模式示例
2017/09/07 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
2017/11/24 Javascript
js操作二进制数据方法
2018/03/03 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
2019/05/10 Javascript
Vue基础学习之项目整合及优化
2019/06/02 Javascript
在SSM框架下用laypage和ajax实现分页和数据交互的方法
2019/09/27 Javascript
在weex中愉快的使用scss的方法步骤
2020/01/02 Javascript
vue学习笔记之Vue中css动画原理简单示例
2020/02/29 Javascript
JS使用for in有序获取对象数据
2020/05/19 Javascript
python列表与元组详解实例
2013/11/01 Python
Python里隐藏的“禅”
2014/06/16 Python
python对html过滤处理的方法
2018/10/21 Python
Python 带有参数的装饰器实例代码详解
2018/12/06 Python
在Python中调用Ping命令,批量IP的方法
2019/01/26 Python
python numpy 反转 reverse示例
2019/12/04 Python
解决jupyter运行pyqt代码内核重启的问题
2020/04/16 Python
记一次django内存异常排查及解决方法
2020/08/07 Python
拿来就用!Python批量合并PDF的示例代码
2020/08/10 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
高三英语教学反思
2014/01/13 职场文书
群众路线教育党员自我剖析材料
2014/10/06 职场文书
机关作风建设自查报告及整改措施
2014/10/21 职场文书
2015年勤工助学工作总结
2015/04/29 职场文书
如何用JavaScript实现一个数组惰性求值库
2021/05/05 Javascript
jdbc中自带MySQL 连接池实践示例
2022/07/23 MySQL