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

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

有时服务器需要执行很耗时的操作,这个操作的结果并不需要返回给客户端。但因为php是同步执行的,所以客户端需要等待服务处理完才可以进行下一步。

因此对于耗时的操作适合异步执行,服务器接收到请求后,处理完客户端需要的数据就返回,再异步在服务器执行耗时的操作。

难点

PHP没有真正实现多线程操作的方法。所以需要通过其它手段来进行模拟多线程。

1.使用Ajax 与 img 标记

 

原理,服务器返回的html中插入Ajax 代码或 img 标记,img的src为需要执行的程序。

 

优点:实现简单,服务端无需执行任何调用

 

缺点:在执行期间,浏览器会一直处于loading状态,因此这种方法并不算真正的异步调用。

 

    $.get("doRequest.php", { name: "fdipzone"} );  
    <img src="doRequest.php?name=fdipzone">  

 

 2.使用popen

resource popen ( string $command , string $mode )

pclose(popen('php /home/fdipzone/doRequest.php &', 'r')); 

 

优点:执行速度快

缺点:1.只能在本机执行

           2.不能传递大量参数

           3.访问量高时会创建很多进程。

 

3.使用curl非阻塞调用

设置curl的超时时间 CURLOPT_TIMEOUT 为1 (最小为1),因此客户端需要等待1秒

 

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

 

 4.使用fsockopen

fsockopen是最好的,缺点是需要自己拼接header部分。

 

<?php
$url = 'http://www.example.com/doRequest.php';  
$param = array(  
    'name'=>'fdipzone',  
    'gender'=>'male',  
    'age'=>30  
);  
  
doRequest($url, $param);  
function doRequest($url, $param=array()){  
  
    $urlinfo = parse_url($url);  
  
    $host = $urlinfo['host'];  
    $path = $urlinfo['path'];  
    $query = isset($param)? http_build_query($param) : '';  
  
    $port = 80;  
    $errno = 0;  
    $errstr = '';  
    $timeout = 10;  
  
    $fp = fsockopen($host, $port, $errno, $errstr, $timeout);  
  
    $out = "POST ".$path." HTTP/1.1\r\n";  
    $out .= "host:".$host."\r\n";  
    $out .= "content-length:".strlen($query)."\r\n";  
    $out .= "content-type:application/x-www-form-urlencoded\r\n";  
    $out .= "connection:close\r\n\r\n";  
    $out .= $query;  
  
    fputs($fp, $out);  
    fclose($fp);  
}
?> 

 

 注意:

1:当执行过程中,客户端连接断开或连接超时,都会有可能造成执行不完整,因此需要加上

ignore_user_abort(true); // 忽略客户端断开  
set_time_limit(0);       // 设置执行不超时 

2:客户端短时间内多次调用a.php,出现部分请求 没有执行b.php 的情况。

解决方法:
在Nginx的nginx.conf文件中,查看worker_processes为1,判断服务端响应请求的线程启动限制太大,得知服务器本身配置为双核CPU,判断2-4线程比较合适,于是修改worker_processes为4.问题得到解决!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值