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