首页 > Web开发 > 详细

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

时间:2015-11-17 16:26:54      阅读:269      评论:0      收藏:0      [点我收藏+]

浏览器和服务器之间是通过 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.问题得到解决!

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

原文:http://www.cnblogs.com/Alight/p/4971771.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!