URL 模似HTTP請求工具,

<?php


/**
* CURL 模似HTTP請求工具,

* 支持以下功能:
* 1:支持ssl連接和proxy代理連接
* 2: 對cookie的自動支持
* 3: 簡單的GET/POST常規操作
* 4: 支持單個文件上傳或同字段的多文件上傳,支持相對路徑或絕對路徑.
* 5: 支持返回發送請求前和請求後所有的服務器信息和服務器Header信息
* 6: 自動支持lighttpd服務器
* 7: 支持自動設置 REFERER 引用頁
* 8: 自動支持服務器301跳轉或重寫問題(謝謝鄭GG)
* 9: 其它可選項,如自定義端口,超時時間,USERAGENT,Gzip壓縮等.

============= 求例如下 ===============
include('clsss/class.curl.php');
$cu = new Curl();

//得到 baidu 的首頁內容
echo $cu->get('http://www.baidu.com');

//登錄到QuickPHP實例中並且得到所有用戶信息
$cu->post('http://www.myquickphp.com/code/qpdemo/?c=main&a=login',array('uname'=>'admin','upass'=>'admin'));
echo $cu->get('http://www.myquickphp.com/code/qpdemo');

//向 http://a.com/a.php 上傳內容和文件, a.php 的測試代碼可以如下:
//<?php print_r($_POST);print_r($_FILES); />
echo $cu->post('http://a.com/a.php',array('id'=>1,'name'=>'yuanwei'),
array('img'=>'file/a.jpg','files'=>array('file/1.zip','file/2.zip')));

//得到所有調試信息
echo '<br/>','ERRNO=',$cu->errno();
echo '<br/>','ERROR=',$cu->error();
echo '<pre>'.print_r($cu->getinfo(),true).'</pre>';

*/
class Curl{

//CURL句柄
private $ch = null;
//CURL執行前後所設置或服務器端返回的信息
private $info = array();
//CURL SETOPT 信息
private $setopt = array(
//訪問的端口,http默認是 80
'port'=>80,
//客戶端 USERAGENT,如:"Mozilla/4.0",爲空則使用用戶的瀏覽器
'userAgent'=>'',
//連接超時時間
'timeOut'=>30,
//是否使用 COOKIE 建議打開,因爲一般網站都會用到
'useCookie'=>true,
//是否支持SSL
'ssl'=>false,
//客戶端是否支持 gzip壓縮
'gzip'=>true,

//是否使用代理
'proxy'=>false,
//代理類型,可選擇 HTTP 或 SOCKS5
'proxyType'=>'HTTP',
//代理的主機地址,如果是 HTTP 方式則要寫成URL形式如:"http://www.proxy.com"
//SOCKS5 方式則直接寫主機域名爲IP的形式,如:"192.168.1.1"
'proxyHost'=>'http://www.proxy.com',
//代理主機的端口
'proxyPort'=>1234,
//代理是否要身份認證(HTTP方式時)
'proxyAuth'=>false,
//認證的方式.可選擇 BASIC 或 NTLM 方式
'proxyAuthType'=>'BASIC',
//認證的用戶名和密碼
'proxyAuthUser'=>'user',
'proxyAuthPwd'=>'password',
);

/**
* 構造函數
*
* @param array $setopt :請參考 private $setopt 來設置
*/
public function __construct($setopt=array())
{
//合併用戶的設置和系統的默認設置
$this->setopt = array_merge($this->setopt,$setopt);
//如果沒有安裝CURL則終止程序
function_exists('curl_init') || die('CURL Library Not Loaded');
//初始化
$this->ch = curl_init();
//設置CURL連接的端口
curl_setopt($this->ch, CURLOPT_PORT, $this->setopt['port']);
//使用代理
if($this->setopt['proxy']){
$proxyType = $this->setopt['proxyType']=='HTTP' ? CURLPROXY_HTTP : CURLPROXY_SOCKS5;
curl_setopt($this->ch, CURLOPT_PROXYTYPE, $proxyType);
curl_setopt($this->ch, CURLOPT_PROXY, $this->setopt['proxyHost']);
curl_setopt($this->ch, CURLOPT_PROXYPORT, $this->setopt['proxyPort']);
//代理要認證
if($this->setopt['proxyAuth']){
$proxyAuthType = $this->setopt['proxyAuthType']=='BASIC' ? CURLAUTH_BASIC : CURLAUTH_NTLM;
curl_setopt($this->ch, CURLOPT_PROXYAUTH, $proxyAuthType);
$user = "[{$this->setopt['proxyAuthUser']}]:[{$this->setopt['proxyAuthPwd']}]";
curl_setopt($this->ch, CURLOPT_PROXYUSERPWD, $user);
}
}
//啓用時會將服務器服務器返回的“Location:”放在header中遞歸的返回給服務器
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
//打開的支持SSL
if($this->setopt['ssl']){
//不對認證證書來源的檢查
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
//從證書中檢查SSL加密算法是否存在
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, true);
}
//設置http頭,支持lighttpd服務器的訪問
$header[]= 'Expect:';
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $header);
//設置 HTTP USERAGENT
$userAgent = $this->setopt['userAgent'] ? $this->setopt['userAgent'] : $_SERVER['HTTP_USER_AGENT'];
curl_setopt($this->ch, CURLOPT_USERAGENT, $userAgent);
//設置連接等待時間,0不等待
curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, $this->setopt['timeOut']);
//設置curl允許執行的最長秒數
curl_setopt($this->ch, CURLOPT_TIMEOUT, $this->setopt['timeOut']);
//設置客戶端是否支持 gzip壓縮
if($this->setopt['gzip']){
curl_setopt($this->ch, CURLOPT_ENCODING, 'gzip');
}
//是否使用到COOKIE
if($this->setopt['useCookie']){
//生成存放臨時COOKIE的文件(要絕對路徑)
$cookfile = tempnam('/tmp','cuk');
//pr(sys_get_temp_dir());
//連接關閉以後,存放cookie信息
curl_setopt($this->ch, CURLOPT_COOKIEJAR, $cookfile);
curl_setopt($this->ch, CURLOPT_COOKIEFILE, $cookfile);
}
//是否將頭文件的信息作爲數據流輸出(HEADER信息),這裏保留報文
curl_setopt($this->ch, CURLOPT_HEADER, true);
//獲取的信息以文件流的形式返回,而不是直接輸出。
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true) ;
curl_setopt($this->ch, CURLOPT_BINARYTRANSFER, true) ;
}

/**
* 以 GET 方式執行請求
*
* @param string $url :請求的URL
* @param array $params :請求的參數,格式如: array('id'=>10,'name'=>'yuanwei')
* @param array $referer :引用頁面,爲空時自動設置,如果服務器有對這個控制的話則一定要設置的.
* @return 錯誤返回:false 正確返回:結果內容
*/
public function get($url,$params=array(), $referer='')
{
return $this->_request('GET', $url, $params, array(), $referer);
}

/**
* 以 POST 方式執行請求
*
* @param string $url :請求的URL
* @param array $params :請求的參數,格式如: array('id'=>10,'name'=>'yuanwei')
* @param array $uploadFile :上傳的文件,支持相對路徑,格式如下
* 單個文件上傳:array('img1'=>'./file/a.jpg')
* 同字段多個文件上傳:array('img'=>array('./file/a.jpg','./file/b.jpg'))
* @param array $referer :引用頁面,引用頁面,爲空時自動設置,如果服務器有對這個控制的話則一定要設置的.
* @return 錯誤返回:false 正確返回:結果內容
*/
public function post($url,$params=array(),$uploadFile=array(), $referer='')
{
return $this->_request('POST', $url, $params, $uploadFile, $referer);
}

/**
* 得到錯誤信息
*
* @return string
*/
public function error()
{
return curl_error($this->ch);
}

/**
* 得到錯誤代碼
*
* @return int
*/
public function errno()
{
return curl_errno($this->ch);
}

/**
* 得到發送請求前和請求後所有的服務器信息和服務器Header信息,其中
* [before] :請求前所設置的信息
* [after] :請求後所有的服務器信息
* [header] :服務器Header報文信息
*
* @return array
*/
public function getInfo()
{
return $this->info;
}

/**
* 析構函數
*
*/
public function __destruct()
{
//關閉CURL
curl_close($this->ch);
}

/**
* 私有方法:執行最終請求
*
* @param string $method :HTTP請求方式
* @param string $url :請求的URL
* @param array $params :請求的參數
* @param array $uploadFile :上傳的文件(只有POST時才生效)
* @param array $referer :引用頁面
* @return 錯誤返回:false 正確返回:結果內容
*/
private function _request($method, $url, $params=array(), $uploadFile=array(), $referer='')
{
//如果是以GET方式請求則要連接到URL後面
if($method == 'GET'){
$url = $this->_parseUrl($url,$params);
}
//設置請求的URL
curl_setopt($this->ch, CURLOPT_URL, $url);
//如果是POST
if($method == 'POST'){
//發送一個常規的POST請求,類型爲:application/x-www-form-urlencoded
curl_setopt($this->ch, CURLOPT_POST, true) ;
//設置POST字段值
$postData = $this->_parsmEncode($params,false);
//如果有上傳文件
if($uploadFile){
foreach($uploadFile as $key=>$file){
if(is_array($file)){
$n = 0;
foreach($file as $f){
//文件必需是絕對路徑
$postData[$key.'['.$n++.']'] = '@'.realpath($f);
}
}else{
$postData[$key] = '@'.realpath($file);
}
}
}
//pr($postData); die;
//設置表單數據
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $postData);
}
//設置了引用頁,否則自動設置
if($referer){
curl_setopt($this->ch, CURLOPT_REFERER, $referer);
}else{
curl_setopt($this->ch, CURLOPT_AUTOREFERER, true);
}
//得到所有設置的信息
$this->info['before'] = curl_getinfo($this->ch);
//開始執行請求
$result = curl_exec($this->ch);
//得到報文頭
$headerSize = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE);
$this->info['header'] = substr($result, 0, $headerSize);
//去掉報文頭
$result = substr($result, $headerSize);
//得到所有包括服務器返回的信息
$this->info['after'] = curl_getinfo($this->ch);
//如果請求成功
if($this->errno() == 0){ //&& $this->info['after']['http_code'] == 200
return $result;
}else{
return false;
}

}

/**
* 返回解析後的URL,GET方式時會用到
*
* @param string $url :URL
* @param array $params :加在URL後的參數
* @return string
*/
private function _parseUrl($url,$params)
{
$fieldStr = $this->_parsmEncode($params);
if($fieldStr){
$url .= strstr($url,'?')===false ? '?' : '&';
$url .= $fieldStr;
}
return $url;
}

/**
* 對參數進行ENCODE編碼
*
* @param array $params :參數
* @param bool $isRetStr : true:以字符串返回 false:以數組返回
* @return string || array
*/
private function _parsmEncode($params,$isRetStr=true)
{
$fieldStr = '';
$spr = '';
$result = array();
foreach($params as $key=>$value){
$value = urlencode($value);
$fieldStr .= $spr.$key .'='. $value;
$spr = '&';
$result[$key] = $value;
}
return $isRetStr ? $fieldStr : $result;
}


}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章