首页 > php开发 > php fsockopen异步处理实例程序

php fsockopen异步处理实例程序

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

例子test.php代码如下:

<?php 
	$domain = "localhost"; 
	$url = '/platform_php_sdk/test4.php'; 
	$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 'send ok!';

test4.php,代码如下:

<?php 
	set_time_limit ( 0 ); 
	ignore_user_abort ( true ); 
	$i = 0; 
	while ( $i ++ < 50 ) { 
	file_put_contents ( $i . '.php', $_REQUEST['email'].$i); 
	sleep ( 3 ); 
	} 
	

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

asynHandle.class.php,代码如下:

<?php 
class AsynHandle { 
    public        $url        = '';        //传入的完整请求url,包括"http://"或"https://" 
    public        $cookie        = array();    //传入的cookie数组,须是键值对 
    public        $post        = array();    //传入的post数组,须是键值对 
    public        $timeout    = 30;        //超时秒数 
    public        $result        = '';        //获取到的数据 
    
    private        $gzip        = true;        //是否开启gzip压缩 
    private        $fop        = NULL;        //fsockopen资源句柄 
    private        $host        = '';        //主机 
    private        $port        = '';        //端口 
    private        $referer    = '';        //伪造来路 
    private        $requestUri    = '';        //实际请求uri 
    private        $header        = '';        //头信息 
    
    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 == ''){return false;} 
        $url_array = parse_url($this->url); 
        !isset($url_array['host']) && $url_array['host'] = '';     
        !isset($url_array['path']) && $url_array['path'] = '';     
        !isset($url_array['query']) && $url_array['query'] = '';     
        !isset($url_array['port']) && $url_array['port'] = 80; 
        
        $this->host            = $url_array['host']; 
        $this->port            = $url_array['port']; 
        $this->referer        = $url_array['scheme'].'://'.$this->host.'/'; 
        $this->requestUri    = $url_array['path'] ? 
                            $url_array['path'].($url_array['query'] ? '?'.$url_array['query'] : '') : '/'; 
        
        switch($url_array['scheme']){ 
            case 'https': 
                $this->fop    = fsockopen('ssl://'.$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) ? 'GET' : 'POST'; 
        $gzip = $this->gzip ? 'gzip, ' : ''; 
        
        //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    .= 'Content-Length: '.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,' 301 ') || strstr($header,' 302 ')){//重定向处理 
            preg_match("/Location:(.*?)$/im",$header,$match); 
            $url = trim($match[1]); 
            preg_match("/Set-Cookie:(.*?)$/im",$header,$match); 
            $cookie    = (emptyempty($match)) ? '' : $match[1]; 
            
            $obj            = new AsynHandle(); 
            $result            = $obj->Get($url, $cookie, $this->post); 
            $this->result    = $result; 
            return $result; 
        }elseif(!strstr($header,' 200 ')){ 
            //找不到域名或网址 
            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('v' ,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['timed_out']){ 
            $h=''; 
            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 = ''; 
            $this->gzip = false; 
            if(strstr($h,'gzip')) $this->gzip = true; 
            while(!($stop && $status['timed_out'] && feof($this->fop))){ 
                if($status['timed_out']) return false; 
                $data = fread($this->fop, ($this->limit == 0 || $this->limit > 128 ? 128 : $this->limit));  
                if($data == ''){//有些服务器不行,须自行判断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 
} 
?>


永久链接:http://www.phprm.com/develop/fs9190.html

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

标签:fsockopen php异步处理

相关文章

发表留言