首页 > 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 = 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
    
}


本文地址:http://www.phprm.com/code/63439.html

转载随意,但请附上文章地址:-)

标签:substr preg_match request

相关文章

发表留言