使用 PHP 使用 fsockopen() 读取网页,但 fgets 不起作用

发布于 2024-09-05 08:03:05 字数 2531 浏览 4 评论 0原文

我在这里使用此代码: http://www.digiways.com/articles/php/httpredirects /

    public function ReadHttpFile($strUrl, $iHttpRedirectMaxRecursiveCalls = 5)
    {
        // parsing the url getting web server name/IP, path and port.
        $url = parse_url($strUrl);
        // setting path to '/' if not present in $strUrl
        if (isset($url['path']) === false)
      $url['path'] = '/';
        // setting port to default HTTP server port 80
        if (isset($url['port']) === false)
     $url['port'] = 80;
        // connecting to the server]



        // reseting class data        
        $this->success = false;
        unset($this->strFile);
        unset($this->aHeaderLines);
        $this->strLocation = $strUrl;
  $fp = fsockopen ($url['host'], $url['port'], $errno, $errstr, 30);
        // Return if the socket was not open $this->success is set to false. 
        if (!$fp)
            return;
  $header = 'GET / HTTP/1.1\r\n';
  $header .= 'Host: '.$url['host'].$url['path'];
  if (isset($url['query']))
   $header .= '?'.$url['query'];
  $header .= '\r\n';
  $header .= 'Connection: Close\r\n\r\n';
  // sending the request to the server
  echo "Header is: <br />".str_replace('\n', '\n<br />', $header)."<br />";
  $length = strlen($header);
  if($length != fwrite($fp, $header, $length))
  {
   echo 'error writing to header, exiting<br />';
   return;
  }
  // $bHeader is set to true while we receive the HTTP header
  // and after the empty line (end of HTTP header) it's set to false.
  $bHeader = true;
  // continuing untill there's no more text to read from the socket
  while (!feof($fp))
  {
   echo "in loop";
   // reading a line of text from the socket
   //  not more than 8192 symbols. 
   $good = $strLine = fgets($fp, 128);
   if(!$good)
   {
    echo 'bad';
    return;
   }
   // removing trailing \n and \r characters.
   $strLine = ereg_replace('[\r\n]', '', $strLine);
   if ($bHeader == false) 
    $this->strFile .= $strLine.'\n';
   else
    $this->aHeaderLines[] = trim($strLine);
   if (strlen($strLine) == 0)
    $bHeader = false;
   echo "read: $strLine<br />";
   return;
  }
  echo "<br />after loop<br />";
  fclose ($fp);

    }

这就是我得到的全部:

Header is:
GET / HTTP/1.1\r\n
Host: www.google.com/\r\n
Connection: Close\r\n\r\n
in loopbad

所以它失败了 fgets($fp, 128);

Im using this code here: http://www.digiways.com/articles/php/httpredirects/

    public function ReadHttpFile($strUrl, $iHttpRedirectMaxRecursiveCalls = 5)
    {
        // parsing the url getting web server name/IP, path and port.
        $url = parse_url($strUrl);
        // setting path to '/' if not present in $strUrl
        if (isset($url['path']) === false)
      $url['path'] = '/';
        // setting port to default HTTP server port 80
        if (isset($url['port']) === false)
     $url['port'] = 80;
        // connecting to the server]



        // reseting class data        
        $this->success = false;
        unset($this->strFile);
        unset($this->aHeaderLines);
        $this->strLocation = $strUrl;
  $fp = fsockopen ($url['host'], $url['port'], $errno, $errstr, 30);
        // Return if the socket was not open $this->success is set to false. 
        if (!$fp)
            return;
  $header = 'GET / HTTP/1.1\r\n';
  $header .= 'Host: '.$url['host'].$url['path'];
  if (isset($url['query']))
   $header .= '?'.$url['query'];
  $header .= '\r\n';
  $header .= 'Connection: Close\r\n\r\n';
  // sending the request to the server
  echo "Header is: <br />".str_replace('\n', '\n<br />', $header)."<br />";
  $length = strlen($header);
  if($length != fwrite($fp, $header, $length))
  {
   echo 'error writing to header, exiting<br />';
   return;
  }
  // $bHeader is set to true while we receive the HTTP header
  // and after the empty line (end of HTTP header) it's set to false.
  $bHeader = true;
  // continuing untill there's no more text to read from the socket
  while (!feof($fp))
  {
   echo "in loop";
   // reading a line of text from the socket
   //  not more than 8192 symbols. 
   $good = $strLine = fgets($fp, 128);
   if(!$good)
   {
    echo 'bad';
    return;
   }
   // removing trailing \n and \r characters.
   $strLine = ereg_replace('[\r\n]', '', $strLine);
   if ($bHeader == false) 
    $this->strFile .= $strLine.'\n';
   else
    $this->aHeaderLines[] = trim($strLine);
   if (strlen($strLine) == 0)
    $bHeader = false;
   echo "read: $strLine<br />";
   return;
  }
  echo "<br />after loop<br />";
  fclose ($fp);

    }

This is all I get:

Header is:
GET / HTTP/1.1\r\n
Host: www.google.com/\r\n
Connection: Close\r\n\r\n
in loopbad

So it fails the fgets($fp, 128);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逆光飞翔i 2024-09-12 08:03:05

您是否有理由不使用 PHP 内置的、默认启用的功能来使用 fopen 获取远程文件?

$remote_page = file_get_contents('http://www.google.com/'); // <- Works!

如果您需要执行诸如获取标头之类的操作而无需费力思考,还有大量高质量的第三方库。尝试使用 Zend_Http_Client 来确定大小。

Is there a reason you aren't using PHP's built-in, enabled-by-default ability to fetch remote files using fopen?

$remote_page = file_get_contents('http://www.google.com/'); // <- Works!

There are also plenty of high-quality third-party libraries, if you need to do something like fetch headers without thinking too hard. Try Zend_Http_Client on for size.

情泪▽动烟 2024-09-12 08:03:05

该缺陷如下:

$good = $strLine = fgets($fp, 128);
if(!$good)
{
 echo 'bad';
 return;
}

fgets() 成功时返回字符串,失败时返回 FALSE。但是,如果没有更多数据要返回,fgets() 将返回空字符串 ('')。因此,$good$strLine 都设置为空字符串,PHP 会在 if() 测试中将其转换为 FALSE。您应该重写如下:

$strLine = fgets($fp, 128);
if ($strLine === FALSE) { // strict comparison - types and values must match
   echo 'bad';
   return;
}

不需要双重赋值,因为您可以直接测试 $strLine

The flaw is here:

$good = $strLine = fgets($fp, 128);
if(!$good)
{
 echo 'bad';
 return;
}

fgets() returns either a string on success, or FALSE on failure. However, if there was no more data to be returned, fgets() will return the empty string (''). So, both $good and $strLine are set to the empty string, which PHP will happily cast to FALSE in the if() test. You should rewrite as follows:

$strLine = fgets($fp, 128);
if ($strLine === FALSE) { // strict comparison - types and values must match
   echo 'bad';
   return;
}

There's no need for the double assignment, as you can test $strLine directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文