2

我用 fsockopen() 和 fread() 读取了一些 URL,我得到了这种数据:

      <li
10 
></li>
      <li
9f 
>asd</li>

d  
          <li
92 

这完全搞砸了O_O

--

在使用 file _ get _ contents() 函数时,我得到了这种数据:

<li></li>
      <li>asd</li>

哪个是对的!那么,到底哪里错了?我在我的 windows 服务器和 linux 服务器上试过,两者的行为都是一样的。他们甚至没有相同的 PHP 版本。

--

我的 PHP 代码是:

$fp = @fsockopen($hostname, 80, $errno, $errstr, 30);
if(!$fp){
    return false;
}else{
    $out = "GET /$path HTTP/1.1\r\n";
    $out .= "Host: $hostname\r\n";
    $out .= "Accept-language: en\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);

    $data = "";
    while(!feof($fp)){
        $data .= fread($fp, 1024);
    }
    fclose($fp);

感谢任何帮助/提示,​​现在一整天都在想:/

哦,我不能使用 fopen() 或 file_get_contents() 因为我的脚本运行的服务器没有启用 fopen 包装器> __ <

我真的很想知道如何解决这个问题,只是出于好奇。而且我认为无论如何我都不能在此服务器上使用任何额外的库。

4

3 回答 3

1

您可能想使用cURL。

<?php
// create a new cURL resource
$ch = curl_init();

// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// grab URL and pass it to the browser
$output = curl_exec($ch);

// close cURL resource, and free up system resources
curl_close($ch);
?>
于 2009-08-14T19:14:39.883 回答
1

关于您的“奇怪数据”问题,这可能是因为您从中请求数据的服务器正在以分块模式传输数据。

在浏览器中调用相同的 URL 时,您可以查看 HTTP 标头;这些标题之一可能是这样的:

Transfer-encoding: chunked


引用维基百科关于此事的文章

每个非空块都以它嵌入的数据的八位字节数(以十六进制写入的大小)开头,然后是 CRLF(回车和换行)和数据本身。然后用 CRLF 关闭块。在一些实现中,空白字符 (0x20) 在块大小和 CRLF 之间填充。

最后一个块是单行,简单地由块大小 (0)、一些可选的填充空白和终止 CRLF 组成。它后面没有任何数据,但可以使用与消息头相同的语法发送可选的尾部。

消息最终由最终的 CRLF 组合关闭。

这看起来接近你得到的......所以我猜这就是问题所在。


据我记得,curl 知道如何处理这个问题——所以,简单的方法是使用curl而不是 fsockopen 等

并且使用 curl 通常比使用套接字更好:它将处理您可能遇到的许多问题;像这个 ;-)


另一个想法是,如果您的服务器上没有启用 curl,则可以使用一些已经存在的基于 fsockopen 的库——希望它已经为您处理了这些事情。

例如,我曾与史努比合作过几次;也许它已经知道如何处理?
(不确定:您必须自己测试——或者查看文档以了解这是否可行)
不过,如果您想自己处理 HTTP 协议的奥秘……好吧,我祝你好运 !

于 2009-08-14T19:25:34.587 回答
1

使用 fsockopen(),您可以获得原始 TCP 数据,而不是 HTTP 内容。我假设您也看到了 HTTP 标头,对吧?如果它采用分块编码,您将获得所有块标头。

这是一个已知的问题。有人在此处发布了有关如何删除块标头的解决方案。

于 2009-08-14T19:57:01.403 回答