首页 > php教程 > php手册 > php fsockopen异步处理实例程序

php fsockopen异步处理实例程序

WBOY
发布: 2016-05-23 08:34:05
原创
1186 人浏览过

php中异步处理数据我们最简单的方法就是使用fsockopen了,下面我来介绍基于fsockopen函数实现的异步处理,希望对各位会带来帮助.

例子test.php代码如下:

<?php 
	$domain = "localhost"; 
	$url = &#39;/platform_php_sdk/test4.php&#39;; 
	$header = "POST $url HTTP/1.0\r\n"; 
	$header .= "Content-Type:application/x-www-form-urlencoded\r\n"; 
	$par = "email=zhangzenglun@163.com"; 
	$header .="Content-Length:".strlen($par)."\r\n\r\n"; 
	$fp = @fsockopen($domain,80,$errno,$errstr,30); 
	fputs($fp, $header.$par); 
	fclose($fp); 
	echo &#39;send ok!&#39;;
登录后复制

test4.php,代码如下:

<?php 
	set_time_limit ( 0 ); 
	ignore_user_abort ( true ); 
	$i = 0; 
	while ( $i ++ < 50 ) { 
	file_put_contents ( $i . &#39;.php&#39;, $_REQUEST[&#39;email&#39;].$i); 
	sleep ( 3 ); 
	} 
	
登录后复制

补充一个异步处理类,该类可以请求HTTP和HTTPS协议,还可以处理301、302重定向以及GZIP压缩等,代码如下.

asynHandle.class.php,代码如下:

<?php 
class AsynHandle { 
    public        $url        = &#39;&#39;;        //传入的完整请求url,包括"http://"或"https://" 
    public        $cookie        = array();    //传入的cookie数组,须是键值对 
    public        $post        = array();    //传入的post数组,须是键值对 
    public        $timeout    = 30;        //超时秒数 
    public        $result        = &#39;&#39;;        //获取到的数据 
    
    private        $gzip        = true;        //是否开启gzip压缩 
    private        $fop        = NULL;        //fsockopen资源句柄 
    private        $host        = &#39;&#39;;        //主机 
    private        $port        = &#39;&#39;;        //端口 
    private        $referer    = &#39;&#39;;        //伪造来路 
    private        $requestUri    = &#39;&#39;;        //实际请求uri 
    private        $header        = &#39;&#39;;        //头信息 
    
    private        $block        = 1;        //网络流状态.1为阻塞,0为非阻塞 
    private        $limit        = 128;        //读取的最大字节数    
    
    //构造函数 
    public function __construct(){ 
        ignore_user_abort(TRUE);//忽略用户中断.如果客户端断开连接,不会引起脚本abort 
        //set_time_limit(0);//取消脚本执行延时上限 
    } 
    //解析URL并创建资源句柄 
    private function analyzeUrl(){ 
        if ($this->url == &#39;&#39;){return false;} 
        $url_array = parse_url($this->url); 
        !isset($url_array[&#39;host&#39;]) && $url_array[&#39;host&#39;] = &#39;&#39;;     
        !isset($url_array[&#39;path&#39;]) && $url_array[&#39;path&#39;] = &#39;&#39;;     
        !isset($url_array[&#39;query&#39;]) && $url_array[&#39;query&#39;] = &#39;&#39;;     
        !isset($url_array[&#39;port&#39;]) && $url_array[&#39;port&#39;] = 80; 
        
        $this->host            = $url_array[&#39;host&#39;]; 
        $this->port            = $url_array[&#39;port&#39;]; 
        $this->referer        = $url_array[&#39;scheme&#39;].&#39;://&#39;.$this->host.&#39;/&#39;; 
        $this->requestUri    = $url_array[&#39;path&#39;] ? 
                            $url_array[&#39;path&#39;].($url_array[&#39;query&#39;] ? &#39;?&#39;.$url_array[&#39;query&#39;] : &#39;&#39;) : &#39;/&#39;; 
        
        switch($url_array[&#39;scheme&#39;]){ 
            case &#39;https&#39;: 
                $this->fop    = fsockopen(&#39;ssl://&#39;.$this->host, 443, $errno, $errstr, $this->timeout); 
                break; 
            default: 
                $this->fop    = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout); 
                break; 
        } 
        
        if(!$this->fop){ 
            $this->result    = "$errstr ($errno)<br />\n"; 
            return false; 
        } 
        return true; 
    }//analyzeUrl end 
    
    //拼装HTTP的header 
    private function assHeader(){ 
        $method = emptyempty($this->post) ? &#39;GET&#39; : &#39;POST&#39;; 
        $gzip = $this->gzip ? &#39;gzip, &#39; : &#39;&#39;; 
        
        //cookie数据 
        if(!emptyempty($htis->cookie)){ 
            $htis->cookie = http_build_cookie($htis->cookie); 
        } 
        
        //post数据 
        if(!emptyempty($this->post)){            
            $this->post = http_build_query($this->post); 
        } 
        
        $header    = "$method $this->requestUri HTTP/1.0\r\n"; 
        $header    .= "Accept: */*\r\n"; 
        $header    .= "Referer: $this->referer\r\n"; 
        $header    .= "Accept-Language: zh-cn\r\n"; 
        if(!emptyempty($this->post)){ 
            $header    .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
        } 
        $header    .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; 
        $header    .= "Host: $this->host\r\n"; 
        if(!emptyempty($this->post)){ 
            $header    .= &#39;Content-Length: &#39;.strlen($this->post)."\r\n"; 
        } 
        $header    .= "Connection: Close\r\n"; 
        $header    .= "Accept-Encoding: {$gzip}deflate\r\n"; 
        $header    .= "Cookie: $this->cookie\r\n\r\n"; 
        $header    .= $this->post; 
        $this->header    = $header; 
    }//assHeader end 
    
    //返回状态检测,301、302重定向处理 
    private function checkRecvHeader($header){ 
        if(strstr($header,&#39; 301 &#39;) || strstr($header,&#39; 302 &#39;)){//重定向处理 
            preg_match("/Location:(.*?)$/im",$header,$match); 
            $url = trim($match[1]); 
            preg_match("/Set-Cookie:(.*?)$/im",$header,$match); 
            $cookie    = (emptyempty($match)) ? &#39;&#39; : $match[1]; 
            
            $obj            = new AsynHandle(); 
            $result            = $obj->Get($url, $cookie, $this->post); 
            $this->result    = $result; 
            return $result; 
        }elseif(!strstr($header,&#39; 200 &#39;)){ 
            //找不到域名或网址 
            return false; 
        }else return 200; 
    }//checkRecvHeader end 
    
    //gzip解压 
    private function gzdecode($data){ 
        $flags = ord(substr($data, 3, 1)); 
        $headerlen = 10; 
        $extralen = 0; 
        $filenamelen = 0; 
        if ($flags & 4) { 
            $extralen = unpack(&#39;v&#39; ,substr($data, 10, 2)); 
            $extralen = $extralen[1]; 
            $headerlen += 2 + $extralen; 
        } 
        if ($flags & 8) $headerlen = strpos($data, chr(0), $headerlen) + 1; 
        if ($flags & 16) $headerlen = strpos($data, chr(0), $headerlen) + 1;  //开源软件:phpfensi.com 
        if ($flags & 2) $headerlen += 2; 
        $unpacked = @gzinflate(substr($data, $headerlen)); 
        if ($unpacked === FALSE) $unpacked = $data; 
        return $unpacked; 
    }//gzdecode end 
    
    //请求函数,只请求,不返回 
    public function Request($url, $cookie=array(), $post=array(), $timeout=3){ 
        $this->url        = $url; 
        $this->cookie    = $cookie; 
        $this->post        = $post; 
        $this->timeout    = $timeout; 
        
        if(!$this->analyzeUrl()){ 
            return $this->result; 
        } 
        $this->assHeader(); 
        
        stream_set_blocking($this->fop, 0);//非阻塞,无须等待 
        fwrite($this->fop, $this->header); 
        fclose($this->fop); 
        return true; 
    }//Request end 
    
    //获取函数,请求并返回 
    public function Get($url, $cookie=array(), $post=array(), $timeout=30){ 
        $this->url        = $url; 
        $this->cookie    = $cookie; 
        $this->post        = $post; 
        $this->timeout    = $timeout; 
        
        if(!$this->analyzeUrl()){ 
            return $this->result; 
        } 
        $this->assHeader(); 
        
        stream_set_blocking($this->fop, $this->block);   
        stream_set_timeout($this->fop, $this->timeout); 
        fwrite($this->fop, $this->header); 
        $status = stream_get_meta_data($this->fop); 
        
        if(!$status[&#39;timed_out&#39;]){ 
            $h=&#39;&#39;; 
            while(!feof($this->fop)){ 
                if(($header = @fgets($this->fop)) && ($header == "\r\n" ||  $header == "\n")){ 
                    break; 
                } 
                $h .= $header; 
            } 
            
            $checkHttp    = $this->checkRecvHeader($h); 
            if($checkHttp!=200){return $checkHttp;} 
            
            $stop = false; 
            $return = &#39;&#39;; 
            $this->gzip = false; 
            if(strstr($h,&#39;gzip&#39;)) $this->gzip = true; 
            while(!($stop && $status[&#39;timed_out&#39;] && feof($this->fop))){ 
                if($status[&#39;timed_out&#39;]) return false; 
                $data = fread($this->fop, ($this->limit == 0 || $this->limit > 128 ? 128 : $this->limit));  
                if($data == &#39;&#39;){//有些服务器不行,须自行判断FOEF 
                    break; 
                } 
                $return    .= $data; 
                if($this->limit){ 
                    $this->limit -= strlen($data); 
                    $stop = $this->limit <= 0; 
                } 
                
            } 
            @fclose($this->fop); 
            $this->result    = $this->gzip ? $this->gzdecode($return) : $return; 
            return $this->result; 
        }else{ 
            return false; 
        } 
    }//Get end 
} 
?>
登录后复制


永久链接:

转载随意!带上文章地址吧。

相关标签:
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门推荐
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板