当前位置:首页 > 代码·功能 > 正文

一个PHP反向代理操作类 PHP反向代理

如果,你用的国内主机。如果,你的主机需要备案。如果,你的备案掉了…网站访问不了?

其实,反向代理可以搞定这一切,只要一枚非国内的VPS就可以简单解决,没有VPS?没关系,通过PHP也可以完成反向代理了,临时弄个虚拟主机就可以搞定了。

不知道反代是什么的,请果断百度。

go

PHP反向代理操作类源码:

<?php
//Source Code: http://www.xiumu.org/technology/php-reverse-proxy-class.shtml
class PhpReverseProxy{
  public $publicBaseURL;
  public $outsideHeaders;
  public $XRequestedWith;
  public $sendPost;
  public $port,$host,$ip,$content,$forward_path,$content_type,$user_agent,
    $XFF,$request_method,$IMS,$cacheTime,$cookie,$authorization;
  private $http_code,$lastModified,$version,$resultHeader;
  const chunkSize = 10000;
  function __construct(){
    $this->version="PHP Reverse Proxy (PRP) 1.0";
    $this->port="8080";
    $this->host="127.0.0.1";
    $this->ip="";
    $this->content="";
    $this->forward_path="";
    $this->path="";
    $this->content_type="";
    $this->user_agent="";
    $this->http_code="";
    $this->XFF="";
    $this->request_method="GET";
    $this->IMS=false;
    $this->cacheTime=72000;
    $this->lastModified=gmdate("D, d M Y H:i:s",time()-72000)." GMT";
    $this->cookie="";
    $this->XRequestedWith = "";
    $this->authorization = "";
  }
  function translateURL($serverName) {
    $this->path=$this->forward_path.$_SERVER['REQUEST_URI'];
    if(IS_SAE)
      return $this->translateServer($serverName).$this->path;
    if($_SERVER['QUERY_STRING']=="")
      return $this->translateServer($serverName).$this->path;
    else
    return $this->translateServer($serverName).$this->path."?".$_SERVER['QUERY_STRING'];
  }
  function translateServer($serverName) {
    $s = empty($_SERVER["HTTPS"]) ? ''
      : ($_SERVER["HTTPS"] == "on") ? "s"
      : "";
    $protocol = $this->left(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;
    if($this->port=="") 
      return $protocol."://".$serverName;
    else
      return $protocol."://".$serverName.":".$this->port;
  }
  function left($s1, $s2) {
    return substr($s1, 0, strpos($s1, $s2));
  }
  function preConnect(){
    $this->user_agent=$_SERVER['HTTP_USER_AGENT'];
    $this->request_method=$_SERVER['REQUEST_METHOD'];
    $tempCookie="";
    foreach ($_COOKIE as $i => $value) {
      $tempCookie=$tempCookie." $i=$_COOKIE[$i];";
    }
    $this->cookie=$tempCookie;
    if(empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
      $this->XFF=$_SERVER['REMOTE_ADDR'];
    } else {
      $this->XFF=$_SERVER['HTTP_X_FORWARDED_FOR'].", ".$_SERVER['REMOTE_ADDR'];
    }
 
  }
  function connect(){
    if(empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])){
      $this->preConnect();
      $ch=curl_init();
      if($this->request_method=="POST"){
        curl_setopt($ch, CURLOPT_POST,1);
 
        $postData = array();
        $filePost = false;
        $uploadPath = 'uploads/';
        if (IS_SAE)
           $uploadPath = SAE_TMP_PATH;
 
        if(count($_FILES)>0){
            if(!is_writable($uploadPath)){
                die('You cannot upload to the specified directory, please CHMOD it to 777.');
            }
            foreach($_FILES as $key => $fileArray){ 
                copy($fileArray["tmp_name"], $uploadPath . $fileArray["name"]);
                $proxyLocation = "@" . $uploadPath . $fileArray["name"] . ";type=" . $fileArray["type"];
                $postData = array($key => $proxyLocation);
                $filePost = true;
            }
        }
 
        foreach($_POST as $key => $value){
            if(!is_array($value)){
          $postData[$key] = $value;
            }
            else{
          $postData[$key] = serialize($value);
            }
        }
 
        if(!$filePost){
            //$postData = http_build_query($postData);
           $postString = "";
           $firstLoop = true;
           foreach($postData as $key => $value){
            $parameterItem = urlencode($key)."=".urlencode($value);
            if($firstLoop){
          $postString .=  $parameterItem;
            }
            else{
          $postString .=  "&".$parameterItem;
            }
            $firstLoop = false; 
           }
           $postData = $postString;
        }
 
        //echo print_r($postData);
 
        //curl_setopt($ch, CURLOPT_VERBOSE, 0);
        //curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
        $this->sendPost =  $postData;
        //var_dump(file_exists(str_replace('@','',$postData['imgfile'])));exit;
        curl_setopt($ch, CURLOPT_POSTFIELDS,$postData);
        //curl_setopt($ch, CURLOPT_POSTFIELDS,file_get_contents($proxyLocation));
        //curl_setopt($ch, CURLOPT_POSTFIELDS,file_get_contents("php://input"));
      }
 
      //gets rid of mulitple ? in URL
      $translateURL =  $this->translateURL(($this->ip)?$this->ip:$this->host);
      if(substr_count($translateURL, "?")>1){
          $firstPos = strpos($translateURL, "?", 0);
          $secondPos = strpos($translateURL, "?", $firstPos + 1);
          $translateURL = substr($translateURL, 0, $secondPos);
      }
 
      curl_setopt($ch,CURLOPT_URL,$translateURL);
 
      $proxyHeaders = array(
          "X-Forwarded-For: ".$this->XFF,
          "User-Agent: ".$this->user_agent,
          "Host: ".$this->host
      );
 
      if(strlen($this->XRequestedWith)>1){
          $proxyHeaders[] = "X-Requested-With: ".$this->XRequestedWith;
          //echo print_r($proxyHeaders);
      }
 
      curl_setopt($ch,CURLOPT_HTTPHEADER, $proxyHeaders);
 
      if($this->cookie!=""){
        curl_setopt($ch,CURLOPT_COOKIE,$this->cookie);
      }
      curl_setopt($ch,CURLOPT_FOLLOWLOCATION,false); 
      curl_setopt($ch,CURLOPT_AUTOREFERER,true); 
      curl_setopt($ch,CURLOPT_HEADER,true);
      curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
 
      $output=curl_exec($ch);
      $info = curl_getinfo( $ch );
      curl_close($ch);
      $this->postConnect($info,$output);
    }else {
      $this->lastModified=$_SERVER['HTTP_IF_MODIFIED_SINCE'];
      $this->IMS=true;
    }
  }
  function postConnect($info,$output){
    $this->content_type=$info["content_type"];
    $this->http_code=$info['http_code'];
    //var_dump($info);exit;
    if(!empty($info['last_modified'])){
      $this->lastModified=$info['last_modified'];
    }
    $this->resultHeader=substr($output,0,$info['header_size']);
    $content = substr($output,$info['header_size']);
 
    if($this->http_code=='200'){
      $this->content=$content;
    }elseif( ($this->http_code=='302' || $this->http_code=='301') && isset($info['redirect_url'])){
      $redirect_url = str_replace($this->host,$_SERVER['HTTP_HOST'],$info['redirect_url']);
      if (IS_SAE)
         $redirect_url = str_replace('http://fetchurl.sae.sina.com.cn/','',$info['redirect_url']);
      header("Location: $redirect_url");
      exit;
    }elseif($this->http_code=='404'){
      header("HTTP/1.1 404 Not Found");
      exit("HTTP/1.1 404 Not Found");
    }elseif($this->http_code=='500'){
      header('HTTP/1.1 500 Internal Server Error');
      exit("HTTP/1.1 500 Internal Server Error");
    }else{
      exit("HTTP/1.1 ".$this->http_code." Internal Server Error");
    }
  }
 
  function output(){
    $currentTimeString=gmdate("D, d M Y H:i:s",time());
    $expiredTime=gmdate("D, d M Y H:i:s",(time()+$this->cacheTime));
 
    $doOriginalHeaders = true;
    if($doOriginalHeaders){
        if($this->IMS){
          header("HTTP/1.1 304 Not Modified");
          header("Date: Wed, $currentTimeString GMT");
          header("Last-Modified: $this->lastModified");
          header("Server: $this->version");
        }else{
 
          header("HTTP/1.1 200 OK");
          header("Date: Wed, $currentTimeString GMT");
          header("Content-Type: ".$this->content_type);
          header("Last-Modified: $this->lastModified");
          header("Cache-Control: max-age=$this->cacheTime");
          header("Expires: $expiredTime GMT");
          header("Server: $this->version");
          preg_match("/Set-Cookie:[^\n]*/i",$this->resultHeader,$result);
          foreach($result as $i=>$value){
            header($result[$i]);
          }
          preg_match("/Content-Encoding:[^\n]*/i",$this->resultHeader,$result);
          foreach($result as $i=>$value){
            //header($result[$i]);
          }
          preg_match("/Transfer-Encoding:[^\n]*/i",$this->resultHeader,$result);
          foreach($result as $i=>$value){
            //header($result[$i]);
          }
          echo($this->content);
          /*
          if(stristr($this->content, "error")){
        echo print_r($this->sendPost);
          }
          */
        }
    }
    else{
        $headerString = $this->resultHeader; //string 
        $headerArray = explode("\n", $headerString);
        foreach($headerArray as $privHeader){
      header($privHeader);
        }
 
        if(stristr($headerString, "Transfer-encoding: chunked")){
      flush();
      ob_flush();
      $i = 0;
      $maxLen = strlen($this->content);
 
      while($i < $maxLen){
          $endChar = $i + self::chunkSize;
          if($endChar >= $maxLen){
        $endChar = $maxLen - 1;
          }
          $chunk = substr($this->content, $i, $endChar);
          $this->dump_chunk($chunk);
          flush();
          ob_flush();
          $i = $i + $endChar;
      }
        }
        else{
       echo($this->content);
        }
 
        //echo "header: ".print_r($headerArray);
        //header($this->resultHeader);
    }
 
  }
 
 
  function dump_chunk($chunk) {
      echo sprintf("%x\r\n", strlen($chunk));
      echo $chunk;
      echo "\r\n";
  }
 
 
  function getOutsideHeaders(){
      $headers = array();
      foreach ($_SERVER as $name => $value){ 
    if (substr($name, 0, 5) == 'HTTP_') { 
        $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); 
        $headers[$name] = $value; 
    }elseif ($name == "CONTENT_TYPE") { 
        $headers["Content-Type"] = $value; 
    }elseif ($name == "CONTENT_LENGTH") { 
        $headers["Content-Length"] = $value; 
    }elseif(stristr($name, "X-Requested-With")) { 
        $headers["X-Requested-With"] = $value;
        $this->XRequestedWith = $value;
    }
      } 
 
      //echo print_r($headers);
 
      $this->outsideHeaders = $headers;
      return $headers;
  }  
 
}
?>

食用方法:

<?php
$proxy=new PhpReverseProxy();
$proxy->port="80";
$proxy->host="http://ihuan.me";
//$proxy->ip="127.0.0.1";
$proxy->forward_path="";
$proxy->connect();
$proxy->output();
?>
标签:
上一篇: 下一篇:

9 条评论

评论加载中...
  1. 5楼
    来自天朝的朋友 谷歌浏览器 Windows 10
    yesyesxx  

    谷歌镜像搭建?

    2016年8月7日 17:30 评论
  2. 4楼
    来自天朝的朋友 火狐浏览器 Windows 10
    淘乐导刊  

    不管风来雨去,到幻杀博客报到是必须地, :cy: ,顺便提高曝光率~~打卡时间:下午7:02:14

    2015年7月16日 19:02 评论
    • 小幻  

      3Q

      2015年7月17日 18:17 评论
  3. 地板
    来自天朝的朋友 J2ME/MIDP Browser Unknow Os
    小年  

    还是技术流

    2015年7月15日 22:31 评论
  4. 板凳
    谷歌浏览器 Windows 8.1
    xiao201261  

    还有 google挂了
    原因 google把所有ip跳到google.com

    2015年7月15日 22:04 评论
    • 小幻  

      我用Nginx可以正常做谷歌的反代

      2015年7月16日 04:21 评论
      • 有vps的嚎~

        2015年7月16日 19:51 评论
        • 小幻  

          就是一穷屌丝。。。

          2015年7月17日 18:16 评论
  5. 沙发
    谷歌浏览器 Windows 8.1
    xiao201261  

    我就不备案 :bobo_ren:

    2015年7月15日 22:03 评论

发表评论

不理你。不要啊!吃饭。吃惊。吃西瓜。飞吻!恭喜!Hi纠结!膜拜!OK抛媚眼。泡泡糖。抛钱。忍!生闷气!调皮。偷看。委屈。献花。疑问?抓狂!

小提示:Ctrl+Enter快速提交助您一臂之力~
加载中……