长河-心灵的窗口

一个完整的http类,估计里面的发送文件方法有些用

上一篇 / 下一篇  2008-04-08 16:18:00 / 个人分类:网页制作


版本更新,在原版本上添加及修改以下内容:
1.去除CURL
2.支持POST文件
3.取消发送下载.(单独分成一个Class了,暂时不方便发上来)
4.支持URL中的中文
复制PHP内容到剪贴板
 
项目中用到,自己收藏一下,以后免得再找了,呵呵....
PHP代码:

<?php
/**
 * 名称:http类
 * 版本:1.0.1 Beta
 * 日期:2007/10/30
 * 支持:lazy => base64_decode('bzBsYXp5MG9AZ21haWwuY29t')
* Log:修复一个手误在原176行大多了一个$this-> 感谢 凡 的反馈
*        修复Referer的判断问题。
 * 描述:
 *     支持GET,HEAD,POST(包括文件上传,文件必须是保存在服务器的)
 *     支持代理,没做过啥测试...将就吧 {^^!}
 *     使用=>
 *            $Demo = new http();
 *             $GetDemo = $Demo->get('http://www.demo.com/pagename.page?var=demo');
 *          echo $GetDemo;
 *             $HeadDemo = $Demo->head('http://www.demo.com/filename.type');
 *             var_dump($HaedDemo);//文件存在返回true否则为false
 *             $PostData = array('username'=>'用户名','password'=>'密码');
 *             $PostDemo = $Demo->post('http://www.demo.com/post.page?action=test',$PostData);
 *             echo $PostDemo;
 *             $PostFile = array('images'=>'./images/demo.jpg','attach'=>'./demo.zip');
 *             $PostDemo = $Demo->post('http://www.demo.com/post.page?action=test',$PostData,$PostFile);
 *             echo $PostDemo;
 *             var_dump($Demo);
 */
//defined('STARTTIME')?null:define('STARTTIME',array_sum(explode(' ',microtime())));
class http
{

    var 
$Handle;
//Socket"句柄"
    
var $Request;
//用于保存HTTP请求字符串
    
var $CRLF="\r\n";
//行结束标示
    
var $Version='1.1';
//HTTP版本
    //var $Debug;
    
    //#代理的没做过啥测试,验证的也不支持,貌似只需加多个Proxy-Authorization: Basic base64_encode("{$User}:{$Pass}");就好了的,不过暂时用不到就不搞了
    
var $ProxyHost;
//代理服务器的IP
    
var $ProxyPort;
//代理服务器的端口
    
var $ProxyUser;
//代理服务器的用户名
    
var $ProxyPass;
//代理服务器的用户密码
    #//代理的没做过啥测试,验证的也不支持,貌似只需加多个Proxy-Authorization: Basic base64_encode("{$User}:{$Pass}");就好了的,不过暂时用不到就不搞了
    
    
var $Server;
//用于保存web服务器的IP
    
var $Port=80;
//web服务器的端口
    
var $Document;
//用于保存HTTP请求的文档

    
var $Header 
= array(
    
'Accept'=>"*/*"
,
    
'Accept-Language'=>"zh-cn,zh"
,
    
'Accept-Encoding'=>"gzip, deflate"
,
    
'User-Agent'=>"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2)"
,
    
'Pragma'=>"no-cache"
,
    
'Cache-Control'=>"no-cache"
,
    
'Host'=>""
,
    
'Referer'=>""
,
    
'Cookie'=>""
,
    
'Connection'=>
"Close"
    
);
//用于保存http的头请求

    
var $Response;
//用于保存服务器的返回状态

    /**
     * 构造函数
     * 在这里暂时没啥用,嗯~不初始化啥了
     */
    
function http(/*$Debug=true*/
){
        
//$this->Debug = $Debug;
    
}

    
/**
     * URL解码函数
     * 把URL中一些中文之类的字符转换为服务器能识别的URL
     */
    
function decode_url($URL,$Method='get'
){
        
$Info parse_url($URL
);
        
$Method strtoupper($Method
);
        empty(
$Info['scheme'])?$Info['scheme']='http':null
;
        if(
strtolower($Info['scheme']) != 'http'
){
            return 
false
;
        }
        
$this->Header['Host'] = empty($Info['host'])?false:$Info['host'
];
        
$this->Server gethostbyname($this->Header['Host'
]);
        if(
ip2long($this->Server)==-|| ip2long($this->Server)==false
){
            return 
false
;
        }
        
$this->Port is_numeric($Info['port'])?intval($Info['port']):empty($Info['port'])?80:false
;
        if(empty(
$Info['path']) || $Info['path']=='/'
){
            return 
$this->Document '/'
;
        }else{
            
$Tmp explode('/',$Info['path'
]);
            
array_shift($Tmp
);
            if(
count($Tmp) == && empty($Info['query'
])){
                return 
$this->Document '/'.($Method=='POST'?urlencode($Tmp[0]):rawurlencode($Tmp[0
]));
            }
            foreach(
$Tmp as $Str
){
                
$T[] = $Method == 'POST'?urlencode($Str):rawurlencode($Str
);
            }
            
$Info['path']='/'.implode('/',$T
);
            if(!empty(
$Info['query'
])){
                
$Info['query'] = str_replace(array('&','&'),'&',$Info['query'
]);
                
$Tmp explode('&',$Info['query'
]);
                foreach(
$Tmp as $Query
){
                    
$Str explode('=',$Query
);
                    if(
preg_match('/%[A-F0-9][A-F0-9]/',$Str[1
])){
                        
$Q[] = ($Method == 'POST'?urlencode($Str[0]):rawurlencode($Str[0])).'='.$Str[1
];
                    }else{
                        
$Q[] = ($Method == 'POST'?urlencode($Str[0]):rawurlencode($Str[0])).'='.($Method == 'POST'?urlencode($Str[1]):rawurlencode($Str[1
]));
                    }
                }
                
$Info['query'] = implode('&',$Q
);
                return 
$this->Document $Info['path'].'?'.$Info['query'
];
            }else{
                return 
$this->Document $Info['path'
];
            }
        }
    }

    function 
connect($Server,$Port,$Timeout=8
){
        
$this->Handle=(!empty($this->ProxyHost) && !empty($this->ProxyPort))?fsockopen($this->ProxyHost,$this->ProxyPort,$ErrorNo,$ErrorStr,$Timeout):fsockopen($Server,$Port,$ErrorNo,$ErrorStr,$Timeout
);
        if(!
$this->Handle
){
            return 
false
;
        }
        return 
$this->Handle
;
    }

    function 
add_head($Name,$Value
){
        return 
$this->Header[$Name] = $Value
;
    }

    function 
make_head($Method
){
        
$Method strtoupper($Method
);
        
$AllowMethod = array('GET','HEAD','POST'
);
        
in_array($Method,$AllowMethod)?null:exit('No Allow HTTP Method'
);
        
$this->Request = (!empty($this->ProxyHost)&&!empty($this->ProxyPort))?"{$Method} http://{$this->Header['Host']}{$this->Document} HTTP/{$this->Version}{$this->CRLF}":"$Method $this->Document HTTP/{$this->Version}{$this->CRLF}"
;
        foreach(
$this->Header as $Key=>$Var
){
            empty(
$Var)?null:$this->Request .= "$Key: $Var{$this->CRLF}"
;
        }
        if(
$Method == 'GET' || $Method == 'HEAD'
){
            
$this->Request .= $this->CRLF
;
        }
    }

    function 
decode_head($Header
){

        
$Regexp="/HTTP\/1\.[01] ([0-9]+) [a-z]+/i"
;
        
preg_match($Regexp,$Header,$Tmp
);
        
$this->Response['status'] = trim($Tmp[1
]);

        
$Regexp="/location:([^\n]+)\n/i"
;
        
preg_match($Regexp,$Header,$Tmp
);
        
$this->Response['redirect'] = trim($Tmp[1
]);

        
$Regexp="/Transfer-Encoding:([^\n]+)\n/i"
;
        
preg_match($Regexp,$Header,$Tmp
);
        
$this->Response['TransferEncoding'] = strtoupper(trim($Tmp[1
]));

        
$Regexp="/Content-Encoding:([^\n]+)\n/i"
;
        
preg_match($Regexp,$Header,$Tmp
);
        
$this->Response['ContentEncoding'] = strtoupper(trim($Tmp[1
]));

        
$Regexp="/Set-Cookie:((?:[^=]+)=(?:[^\n;]+)).*/i"
;
        
preg_match_all($Regexp,$Header,$Tmp
);
        foreach(
$Tmp[1] as $Var
){
            
$Var=trim($Var
);
            
$this->Header['Cookie'].="$Var;"
;
        }

        return 
true
;
    }

    function 
decode_body($String,$EOF="\r\n"
){
        if(
strtoupper($this->Response['TransferEncoding'])=='CHUNKED'
){
            
$Return=null
;
            
$EndLength=strlen($EOF
);
            do{
                
$String=ltrim($String
);
                
$StartPos=strpos($String,$EOF
);
                
$Length=hexdec(substr($String,0,$StartPos
));
                if(
$this->Response['ContentEncoding']=='DEFLATE' || $this->Response['ContentEncoding']=='GZIP'
){
                    
$Return.=gzinflate(substr($String,($StartPos+$EndLength+10),$Length
));
                }else{
                    
$Return.=substr($String,($StartPos+$EndLength),$Length
);
                }
                
$String=substr($String,($Length+$StartPos+$EndLength
));
                
$End=trim($String
);
            }while(!empty(
$End
));
            return 
$Return
;
        }elseif(
strtoupper($this->Response['ContentEncoding']) == 'GZIP' || strtoupper($this->Response['ContentEncoding']) == 'DEFLATE'
){
            return 
gzinflate(substr($String,10
));
        }else{
            return 
$String
;
        }
    }

    function 
process($Data=null
){
        if(!
$this->Handle
){
            return 
false
;
        }
        
fwrite($this->Handle,$this->Request,strlen($this->Request
));
        
//#http协议说了第一个CRLF前的部分为HTTP头,后面的才是"内容"
        
do{
            
$Response.=fgets($this->Handle,512
);
        }while(
strpos($Response,"\r\n\r\n") === false
);
        
#//http协议说了第一个CRLF前的部分为HTTP头,后面的才是"内容"

        
$this->decode_head($Response
);
        
$Response=null
;

        while(!
feof($this->Handle
)){
            
$Response.=fgets($this->Handle,1024
);
        }
        
fclose($this->Handle
);
        return 
$this->decode_body($Response
);
    }

    function 
get($URL
){
        if(
$this->decode_url($URL,'GET') == false
){
            return 
false
;
        }
        if(empty(
$this->Header['Referer'
])){
            
$this->Header['Referer']="http://{$this->Header['Host']}{$this->Document}"
;
        }
        if(
$this->connect($this->Server,$this->Port)==false
){
            return 
false
;
        }
        
$this->make_head('get'
);
        return 
$this->process
();
    }

    function 
head($URL
){
        if(
$this->decode_url($URL,'HEAD') == false
){
            return 
false
;
        }
        if(
$this->connect($this->Server,$this->Port)==false
){
            return 
false
;
        }
        
$this->make_head('HEAD'
);
        
$this->process
();
        return 
$this->Response['status']==200?true:false
;
    }

    function 
post($URL,$Data,$File=null
){
        if(!
is_array($Data
)){
            exit(
'The Data Must Be Array'
);
        }
        if(!empty(
$File
)){

TAG: PHP php 文件 下载 POST Class

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-09-28  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 150427
  • 日志数: 43
  • 图片数: 2
  • 影音数: 18
  • 文件数: 32
  • 书签数: 186
  • 建立时间: 2007-09-20
  • 更新时间: 2008-06-29

RSS订阅