PHP CURL 代理

<?php

class Proxy_Http {
//use agent
private $agent = '';//代理
    //get or post
private $method = "GET";
//get data from where
private $url;
//parameters post
private $postParam = array();
//referer
private $referer;
//超时
private $timeout = 30;
//cookie
private $cookie;
// 是否直接输出数据,避免内存溢出
private $isDirectOutput = false;

/**
     *设置agent
     *@param
*/
public function setAgent($agent) {
$this->agent = $agent;
    }
/**
     *设置http方法,get,post
     *@param
*/
public function setMethod($method) {
$this->method = $method;
    }
/**
     *设置url
     *@param
*/
public function setUrl($url) {
$this->url = $this->host . $url;
    }
/**
     *@param
*@return
*/
public function setCookie($cookie) {
$this->cookie = "";
foreach($cookie as $key => $value) {
$this->cookie .= "{$key}={$value};";
        }
    }

/**
     * 设置post参数
     * @param array $postParm
     * @return object
     */
public function setPostParam($postParam) {
$this->postParam = self::flattenArr($postParam);
return $this;
    }

/**
     * php://input
     * @param string $input
     * @return object
     */
public function setRawPostParam($input) {
$this->postParam = $input;
return $this;
    }

/**
     * 多维数组转为一维
     *
     * from
     * array(
     *      'list' => array(
     *           array('a' => b, 'c' => 'd')
     *      ),
     * );
     *
     * to
     * array('list[0][a]' => b, 'list[0][c]' => d)
     *
     * @param array $array
     * @param string $prefix
     * @return array
     */
private static function flattenArr($array, $prefix = '') {
$result = array();
foreach ($array as $key => $value) {
$key = $prefix ? $prefix.'['.$key.']' : $key;
if (is_array($value)) {
$result += self::flattenArr($value, $key);
            } else {
$result[$key] = $value;
            }
        }
return $result;
    }

/**
     *设置files
     *@param
*/
public function setFiles($files) {
$fileData = array();
foreach ($files as $key => $file) {
$fileData[$key] = implode(';', array(
'@'.realpath($file['tmp_name']),
'type='.$file['type'],
'filename='.$file['name'],
            ));
        }
$this->postParam = array_merge($fileData, $this->postParam);
    }
/**
     *设置refer
     *@param
*/
public function setReferer($referer) {
$this->referer = $referer;
    }
/**
     *设置headers
     *@param
*/
public function setHeaders($headers) {
$this->headers = $headers;
    }
/**
     *设置超时
     *@param
*/
public function getTimeout($timeout) {
$this->timeout = $timeout;
    }

/**
     * 是否直接输出
     *
     * @param bool $isDirectOutput
     * @return object
     */
public function setDirectOutput($isDirectOutput) {
$this->isDirectOutput = $isDirectOutput;
return $this;
    }

/**
     * 发送请求
     * @param void
     * @return mixed
     */
public function doRequest() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, !$this->isDirectOutput);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

if (!empty($this->agent)) {
curl_setopt($ch, CURLOPT_USERAGENT,$this->agent);
        }

if (!empty($this->postParam)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postParam);
        }

if (!empty($this->referer)) {
curl_setopt($ch, CURLOPT_REFERER , $this->referer);
        }

if ($this->cookie != false){
curl_setopt($ch, CURLOPT_COOKIE, $this->cookie);
        }

if (!empty($this->headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        }

if ($this->isDirectOutput) {
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'readCurlHeader'));
curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'readCurlData'));
        }

$response = curl_exec($ch);
if (curl_errno($ch)) {
return false;
        }

$body = '';
if (!$this->isDirectOutput) {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$this->responseHeader = substr($response, 0, $headerSize);
$this->showHeaders();
$body = substr($response, $headerSize);
        }
curl_close($ch);
return $body;
    }

/**
     * @param object $curl
     * @param string $data
     * @return int
     */
private function readCurlHeader($curl, $header) {
if (!self::isNeedfilter($header)) {
header($header);
        }
return strlen($header);
    }

/**
     * @param object $curl
     * @param string $data
     * @return int
     */
private function readCurlData($curl, $data) {
echo $data;
return strlen($data);
    }

/**
     * @brief 返回reponseheader
     * @param
* @return
*/
public function getResponseHeaders() {
return $this->responseHeader;
    }

/**
     * @breif 绚烂输出的header
     * @param
* @return
*/
public function showHeaders() {
$arrHeader = explode("\r\n", $this->responseHeader);
foreach($arrHeader as $header) {
if (empty($header) || self::isNeedfilter($header)) {
continue;
            }
header($header);
        }
    }

/**
     * 是否需要过滤 header
     *
     * @param string $header
     * @return bool
     */
private static function isNeedfilter($header) {
static $headers = array(
'Connection',
'Content-Encoding',
'Date',
'Server',
'Set-Cookie',
'tracecode',
'Transfer-Encoding',
'Vary',
        );

if (strpos($header, ':') === false) {
return false;
        }

list($key, $value) = explode(':', $header);
if (in_array($key, $headers)) {
return true;
        }

return false;
    }
}


function curlDispatch() {
//转发请求
$urlHelper = new Proxy_Http();
$url = 'http://test.com';
$_GET['name'] = 'aa';
$_GET['id'] = 'test';
if (!empty($_GET)) {
$url .= "?" . http_build_query($_GET);
    }
$urlHelper->setHeaders(array(
"ID:1223",
"name:testname",
    ));
$urlHelper->setUrl($url);
if (!empty($_POST)) {
$urlHelper->setPostParam($_POST);
    }
if (!empty($_FILES)) {
$urlHelper->setFiles($_FILES);
    }
if(!empty($_COOKIE)) {
$urlHelper->setCookie($_COOKIE);
    }
$input = file_get_contents('php://input');
if (!empty($input) && empty($_POST)) {
$urlHelper->setRawPostParam(urlencode($input));
    }

// doRequest 直接输出内容
$needDirectOutput = array(
'file/download',    // 文件下载
);
$controller = '';
$action = '';
//跟进请求的链接判断是否需要输出内容
if (in_array($controller.'/'.$action, $needDirectOutput)) {
$urlHelper->setDirectOutput(true);
    }
$result = $urlHelper->doRequest();
echo $result;die;
}

curlDispatch();