详解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 相关文章推荐
PHP4 与 MySQL 数据库操作函数详解
Oct 09 PHP
攻克CakePHP系列一 连接MySQL数据库
Oct 22 PHP
php UBB 解析实现代码
Nov 27 PHP
php 带逗号千位符数字的处理方法
Jan 10 PHP
解析zend studio中直接导入svn中的项目的方法步骤
Jun 21 PHP
PHP中捕获超时事件的方法实例
Feb 12 PHP
Apache服务器下防止图片盗链的办法
Jul 06 PHP
CI分页类首页、尾页不显示的解决方法
Mar 28 PHP
PHP目录与文件操作技巧总结(创建,删除,遍历,读写,修改等)
Sep 11 PHP
ubutu 16.04环境下,PHP与mysql数据库,网页登录验证实例讲解
Jul 20 PHP
Yii2框架自定义验证规则操作示例
Feb 08 PHP
Laravel 连接(Join)示例
Oct 16 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生成随机密码类分享
2014/06/25 PHP
PHP上传图片时判断上传文件是否为可用图片的方法
2016/10/20 PHP
Laravel访问出错提示:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or di解决方法
2019/04/02 PHP
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
影响jQuery使用的14个方面
2014/09/01 Javascript
一个JavaScript操作元素定位元素的实例
2014/10/29 Javascript
jQuery中clone()方法用法实例
2015/01/16 Javascript
Vue AST源码解析第一篇
2017/07/19 Javascript
vue webuploader 文件上传组件开发
2017/09/23 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
2018/11/23 Javascript
mpvue+vant app搭建微信小程序的方法步骤
2019/02/11 Javascript
JavaScript实现图片伪异步上传过程解析
2020/04/10 Javascript
jquery更改元素属性attr()方法操作示例
2020/05/22 jQuery
[48:48]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Dream TIME
2014/05/21 DOTA
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
如何处理Python3.4 使用pymssql 乱码问题
2016/01/08 Python
python安装PIL模块时Unable to find vcvarsall.bat错误的解决方法
2016/09/19 Python
利用python将图片转换成excel文档格式
2017/12/30 Python
python语音识别实践之百度语音API
2018/08/30 Python
实例讲解python中的序列化知识点
2018/10/08 Python
Python 绘制酷炫的三维图步骤详解
2019/07/12 Python
python实现将中文日期转换为数字日期
2020/07/14 Python
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
美国购物网站:Clickhere2shop
2021/01/28 全球购物
如何通过jdbc调用存储过程
2012/04/19 面试题
动物学专业毕业生求职信
2013/10/11 职场文书
毕业生造价工程师求职信
2013/10/17 职场文书
养殖人员的创业计划书范文
2013/12/26 职场文书
历史专业学生的自我评价
2014/02/28 职场文书
《守株待兔》教学反思
2014/03/01 职场文书
大四毕业生自荐书
2014/07/05 职场文书
学校消防安全责任书
2014/07/23 职场文书
2014年幼儿园安全工作总结
2014/11/10 职场文书
学生会个人总结范文
2015/02/15 职场文书
民主生活会主持词
2015/07/01 职场文书
值班管理制度范本
2015/08/06 职场文书