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

一个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();
?>
标签:
上一篇: 下一篇:

11 条评论

评论加载中...
  1. 7楼
    United Kingdom 火狐浏览器 Windows Vista
    UK Chat Rooms  

    483735 255246Youre so cool! I dont suppose Ive read anything in this way before. So nice to locate somebody by original thoughts on this subject. realy thanks for beginning this up. this fabulous web site is one thing that is necessary on the internet, a person with a bit of originality. beneficial project for bringing a new challenge towards internet! 316106

    2018年8月15日 23:17 评论
  2. 6楼
    来自天朝的朋友 谷歌浏览器 Windows 7
    zlife  

    $proxy->host=”http://ihuan.me”;

    这里代码错了,应该是

    $proxy->host=”ihuan.me”;

    2018年2月3日 21:14 评论
  3. 5楼
    来自天朝的朋友 谷歌浏览器 Windows 10
    yesyesxx  

    谷歌镜像搭建?

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

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

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

      3Q

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

    还是技术流

    2015年7月15日 22:31 评论
  6. 板凳
    谷歌浏览器 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 评论
  7. 沙发
    谷歌浏览器 Windows 8.1
    xiao201261  

    我就不备案 :bobo_ren:

    2015年7月15日 22:03 评论

发表评论

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

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