• 技术文章 >php教程 >PHP源码

    php fsockopen异步处理实例程序

    2016-06-08 17:21:45原创567
    php中异步处理数据我们最简单的方法就是使用fsockopen了,下面我来介绍基于fsockopen函数实现的异步处理,希望对各位会带来帮助。

    例子

    test.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

    代码如下 复制代码

    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:

    代码如下 复制代码


    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.'//m.sbmmt.com/m/';
    $this->requestUri = $url_array['path'] ?
    $url_array['path'].($url_array['query'] ? '?'.$url_array['query'] : '') : '//m.sbmmt.com/m/';

    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)
    \n";
    return false;
    }
    return true;
    }//analyzeUrl end

    //拼装HTTP的header
    private function assHeader(){
    $method = empty($this->post) ? 'GET' : 'POST';
    $gzip = $this->gzip ? 'gzip, ' : '';

    //cookie数据
    if(!empty($htis->cookie)){
    $htis->cookie = http_build_cookie($htis->cookie);
    }

    //post数据
    if(!empty($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(!empty($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(!empty($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 = (empty($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;
    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
    }

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:nbsp this quot gt header
    上一篇:深入分析PHP文章内容分页 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • 用PHP实现小写金额转换大写金额【精确到分】• 检测移动设备的php代码(手机访问)• php xml 保存到array数组• PHP禁止图片文件的被盗链函数• 极简的创建文件夹函数
    1/1

    PHP中文网