详解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 相关文章推荐
使用TinyButStrong模板引擎来做WEB开发
Mar 16 PHP
set_include_path在win和linux下的区别
Jan 10 PHP
php判断输入不超过mysql的varchar字段的长度范围
Jun 24 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 PHP
PHP基于php_imagick_st-Q8.dll实现JPG合成GIF图片的方法
Jul 11 PHP
PHP清除字符串中所有无用标签的方法
Dec 01 PHP
Windows下Apache + PHP SESSION丢失的解决过程全纪录
Apr 07 PHP
PHP实现微信发红包程序
Aug 24 PHP
双冒号 ::在PHP中的使用情况
Nov 05 PHP
一个简单安全的PHP验证码类、PHP验证码
Sep 24 PHP
Yii2设置默认控制器的两种方法
May 19 PHP
Mac系统完美安装PHP7详细教程
Jun 06 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
PR值查询 | PageRank 查询
2006/12/20 PHP
escape unescape的php下的实现方法
2007/04/27 PHP
《PHP编程最快明白》第六讲:Mysql数据库操作
2010/11/01 PHP
探讨PHP中this,self,parent的区别详解
2013/06/08 PHP
php通过session防url攻击方法
2014/12/10 PHP
Docker配置PHP开发环境教程
2016/12/21 PHP
PHP过滤器 filter_has_var() 函数用法实例分析
2020/04/23 PHP
JavaScript Date对象 日期获取函数
2010/12/19 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
2015/06/05 Javascript
jQuery解决input超多的表单提交
2015/08/10 Javascript
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
2018/01/27 Javascript
puppeteer库入门初探
2019/01/09 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
[22:20]初生之犊-TI4第5名LGD战队纪录片
2014/08/13 DOTA
[06:25]第二届DOTA2亚洲邀请赛主赛事第二天比赛集锦.mp4
2017/04/03 DOTA
Python中的闭包实例详解
2014/08/29 Python
Python爬取网页中的图片(搜狗图片)详解
2017/03/23 Python
Python如何通过subprocess调用adb命令详解
2017/08/27 Python
Python FTP两个文件夹间的同步实例代码
2018/05/25 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
python面向对象 反射原理解析
2019/08/12 Python
wxPython修改文本框颜色过程解析
2020/02/14 Python
Python操作Excel工作簿的示例代码(\*.xlsx)
2020/03/23 Python
Python图片处理模块PIL操作方法(pillow)
2020/04/07 Python
python如何查看网页代码
2020/06/07 Python
Marriott中国:万豪国际酒店查询预订
2016/09/02 全球购物
TecoBuy澳大利亚:在线电子和小工具商店
2020/06/25 全球购物
人力管理专业毕业生求职信
2014/02/27 职场文书
养生餐厅创业计划书范文
2014/03/26 职场文书
活动倡议书范文
2014/05/13 职场文书
工厂车间标语
2014/06/19 职场文书
会议接待欢迎标语
2014/10/08 职场文书
大学生考试作弊检讨书1000字
2014/10/14 职场文书
2014年勤工助学工作总结
2014/11/24 职场文书