<?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();