例子
test.php
代码如下 复制代码
test4.php
代码如下 复制代码
补充一个异步处理类
该类可以请求http和https协议,还可以处理301、302重定向以及gzip压缩等。
代码如下
asynhandle.class.php:
代码如下 复制代码
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)
\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 }
}
@fclose($this->fop);
$this->result = $this->gzip ? $this->gzdecode($return) : $return;
return $this->result;
}else{
return false;
}
}//get end
}
