用户操作
[即时聊天] [发私信] [加为好友]
张晖ID:btmao
677次访问,排名2万外,好友0人,关注者0人。
btmao的文章
原创 1 篇
翻译 0 篇
转载 1 篇
评论 1 篇
最近评论
EvilOctal:沙发。
文章分类
    收藏
      相册
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 解决PHP中fopen容易超时的问题收藏

      新一篇: smarty变量调节器 | 

      为了从远程读取网页内容,我们常常用需要用PHP打开网页文件,而当网页文件很大或者网页根本不存在的时候,我们发现使用fopen的方法经常会出现超时。于是我们需要一个更加稳定的方法来解决这个问题。

      我们想到使用fsockopen来帮助我们完成工作。fsockopen是定下在network function下的一个函数,他使用的是socket来打开文件。

      resource fsockopen ( string $hostname [, int $port [, int &$errno [, string &$errstr [, float $timeout ]]]] )

      我们定义了一个类叫做http,下面是详细的代码。

      <?php
      class http
      {
          
      function forge_http_packet($url, & $host, & $port, & $packet)
          {
              
      // sure about the $url is start with "http://"

              
      $strpos = strpos($url, '/', 7);
              
      $filename =  substr($url, $strpos, strlen($url- $strpos);

              
      $strpos2 = strpos($url, ':' , 7);
              
      if ($strpos2 == false || $strpos2 > $strpos)
              {
                  
      $host = substr($url, 7, $strpos - 7);
                  
      $port = 80;
              }
              
      else
              {
                  
      $host = substr($url, 7, $strpos2 - 7);
                  
      $port = intval(substr($url, $strpos2 + 1, $strpos - $strpos2 - 1));
              }

              
      $encode_filename = str_replace(' ', '%20', $filename);

              
      $packet  = "GET ".$encode_filename." HTTP/1.1 ";
              
      $packet .= "Accept: */* ";
              
      $packet .= "Host: ".$host." ";
              
      $packet .= "User-Agent: OpenWebSpider ";
          }

          
      function chunked_result($chunked_html)
          {
              
      $html = "";
              
      $start_pos = 0;
              
      while ($start_pos < strlen($chunked_html))
              {
                  
      $final_pos = strpos($chunked_html, " ", $start_pos);
                  
      $chunked_length = $this->hex2dec(substr($chunked_html, $start_pos, $final_pos - $start_pos));
                  
      $buf_html = substr($chunked_html, $final_pos + 2, $chunked_length);
                  
      $html .= $buf_html;
                  
      $start_pos = $final_pos + $chunked_length + 4;
              }
              
      return $html;
          }

          
      function hex2dec($hexstr)
          {
              
      $num = 0;
              
      for ($i = 0 ; $i < strlen($hexstr) ; $i++)
              {
                  
      $num = $num * 16;
                  
      if ($hexstr[$i>= '0' && $hexstr[$i<= '9')
                      
      $num += ord($hexstr[$i]) - ord('0');
                  
      if ($hexstr[$i>= 'A' && $hexstr[$i<= 'F')
                      
      $num += ord($hexstr[$i]) - ord('A'+ 10;
                  
      if ($hexstr[$i>= 'a' && $hexstr[$i<= 'f')
                      
      $num += ord($hexstr[$i]) - ord('a'+ 10;
              }
              
      return $num;
          }

          
      function read_from_url($url)
          {
              
      $total_len = 0;
              
      $this->forge_http_packet($url, $host, $port, $packet);
              
      $handle = fsockopen($host, $port, $errno, $errstr, 5);
              
      if ($handle) {
                  
      fwrite($handle, $packet);

                  
      $result = "";
                  
      while (!feof($handle)) {

                      
      stream_set_timeout($handle, 10);
                      
      $buffer = fgets($handle, 4096);        //4K per 20 sec
                      $info = stream_get_meta_data($handle);
                      
      if ($info['timed_out']) 
                      {
                          
      break;
                      }
                      
      $total_len += strlen($buffer);
                      
      $result .= $buffer;
                      
      if ($total_len > 1000000)
                      {    
      // more than 2M filesize, properly not correct url for news or list
                          return "";
                      }
                  }
                  
      fclose($handle);

                  
      $pos =  strpos($result, " ");
                  
      $header = substr($result, 0, $pos + 4);

                  
      if (strncasecmp($result, "HTTP/1.0 302", 12== 0 ||
                      
      strncasecmp($result, "HTTP/1.1 302", 12== 0 ||
                      
      strncasecmp($result, "HTTP/1.0 301", 12== 0 ||
                      
      strncasecmp($result, "HTTP/1.1 301", 12== 0)
                  {
                      
      $new_url_pos = strpos($result, " Location:");
                      
      if ($new_url_pos === falsereturn "";
                      
      $new_url_pos += 11;
                      
      $new_url_pos2 = strpos($result, " ", $new_url_pos);
                      
      return $this->read_body_from_url(trim(substr($result, 
                          
      $new_url_pos, $new_url_pos2 - $new_url_pos + 1)));
                  }
                  
      else if (strncasecmp($result, "HTTP/1.0 4", 10== 0 ||
                       
      strncasecmp($result, "HTTP/1.1 4", 10== 0 ||
                       
      strncasecmp($result, "HTTP/1.0 5", 10== 0 ||
                       
      strncasecmp($result, "HTTP/1.1 5", 10== 0)
                  {
                      
      $pos2 = strpos($result, " ");
                      
      return substr($result, 0, $pos2);
                  }

                  
      if (strstr($header, "Transfer-Encoding: chunked"== false
                      
      return strstr($result, " ");
                  
      return $this->chunked_result(substr($result, $pos + 4, strlen($result- ($pos + 4)));
              } 
              
      return "";
          }
      }
      ?>

      只需要调用上述类中的函数read_from_url($url)便可以完成工作。

      发表于 @ 2008年04月11日 18:33:00|评论(loading...)|编辑

      新一篇: smarty变量调节器 | 

      评论

      #EvilOctal 发表于2008-04-17 18:25:09  IP: 125.73.94.*
      沙发。
      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © btmao