浏览器和服务器之间是通过 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);
}
所以,总体来看,最好用,最简单的还是第一种方法。
最完美的应该是最后一种,但是比较复杂
如果有更好的办法,欢迎交流。

PHP实现异步调用方法研究的更多相关文章

  1. php分享十一:PHP实现异步调用方法研究

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

  2. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

  3. php异步调用方法实现示例

    php 异步调用方法   客户端与服务器端是通过HTTP协议进行连接通讯,客户端发起请求,服务器端接收到请求后执行处理,并返回处理结果.   有时服务器需要执行很耗时的操作,这个操作的结果并不需要返回 ...

  4. 微信小程序:封装全局的promise异步调用方法

    微信小程序:封装全局的promise异步调用方法 一:封装 function POST(url, params) { let promise = new Promise(function (resol ...

  5. SpringBoot 异步调用方法并接收返回值

    项目中肯定会遇到异步调用其他方法的场景,比如有个计算过程,需要计算很多个指标的值,但是每个指标计算的效率快慢不同,如果采用同步执行的方式,运行这一个过程的时间是计算所有指标的时间之和.比如: 方法A: ...

  6. 浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法(转载)

    在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们发现程序执行完后并没有获取到我们想要的值,这时很有可能是因为你用的是ajax的异步调用async:t ...

  7. C#的同步和异步调用方法

    同步和异步大家都明白什么意思,在这里不多介绍了. namespace ConsoleTest { class Program { static void Main(string[] args) { C ...

  8. java异步调用方法

    一.利用多线程 直接new线程 Thread t = new Thread(){ @Override public void run() { longTimeMethod(); } }; 使用线程池 ...

  9. php如何进行多进程与异步调用方法

    浏览器和服务器之间只一种面向无连接的HTTP协议进行通讯的,面向无连接的程序的特点是客户端请求服务端,服务端根据请求输出相应的程序,不能保持持久连接. 这样就出现了一个问题,一个客户端的相应服务端可能 ...

随机推荐

  1. makefile函数

    http://www.cnblogs.com/tianyajuanke/archive/2013/02/16/2610276.html 通用步骤: 编译时,可以不知钉头文件,如果指定头文件,其作用是当 ...

  2. NPOIHelper

    public class NPOIHelper { public static void WriteDataToExceel(string fileName, DataSet ds) { if (Fi ...

  3. AJAX怎么用POST 传参数

    //注册回调函数.注意注册回调函数是不能加括号,加了会把函数的值返回给onreadystatechange xmlhttp.onreadystatechange = callback; //设置连接信 ...

  4. php 升级排错

    lnmp 环境下,升级php版本,模块都加载完成,数据库,nginx 设置都完好,但php 只能用ip 访问数据库,不能用localhost,处理要设置php.ini 的三个mysqld.sock,还 ...

  5. OAF_开发系列10_实现OAF动态LOV设定

    20150712 Created By BaoXinjian

  6. SharePrecences--(json+sharePrecences)存list 或对象

    利用Gson和SharePreference存储结构化数据 具体的步骤 这个假设有三个User对象生成一个ArrayList<User>: User user1 = new User(&q ...

  7. [转]Amazon AWS亚马逊云服务免费一年VPS主机成功申请和使用方法

    今天部落将再次为大家介绍如何成功申请到来自亚马逊的Amazon AWS免费一年的VPS主机服务.亚马逊公司这个就不用介绍了,是美国最大的一家网络电子商务公司,亚马逊弹性计算云Amazon EC2更是鼎 ...

  8. 前后台读取Web.config中的值的方法

    webconfig <configuration> <appSettings> <add key="Workflow_Url" value=" ...

  9. Silverlight 页面传值问题(转)

    共有两种方式来传递初始化参数 1)在html或者aspx页面中object对象中加入一下代码 参数格式:参数名 = 值,参数名 = 值,... <param name="initPar ...

  10. iOS 设置铃声---加载音乐和音频然后进行播放

    在有些应用中需要用到背景音乐和音效,那在程序中是这么实现的. 1.首先加载背景音乐需要用到AVFoundation框架 2.音乐资源都是在包里的,所以需要获得包路径,涉及方法- (id)initWit ...