【问题标题】:File is not retrieved and saved correctly ( only 2 lines of code )文件未正确检索和保存(只有 2 行代码)
【发布时间】:2026-01-19 16:45:02
【问题描述】:

我已将一个错误隔离为 2 行代码:

    $file = @file_get_contents( "http://d36xtkk24g8jdx.cloudfront.net/bluebar/e2609e5/images/ico/favicon.ico" );

    // echo $file;  // verfied file is populated 

    echo file_put_contents("../favicons/" . "instagram_com.ico", $file); // verifed bytes saved

我发现在浏览器中查看内容时有实际数据。

如果你愿意,看看上面HERE 的输出。

但是,保存的文件在我的客户端或服务器上似乎不是 .ico。

尽管文件扩展名正确,但我不会让我上传它,因为它被正确检测为不是图像文件。

通过将链接粘贴到浏览器的url中很容易获得正确的文件。

http://d36xtkk24g8jdx.cloudfront.net/bluebar/e2609e5/images/ico/favicon.ico

只需使用save as 下载即可。

但是,我需要自动版本工作,但不知道如何进一步解决此问题。

我确认file_get_contents 确实获得了内容,并且file_put_contents 实际上保存了内容。

但是,它不是一个有效的图像文件。

【问题讨论】:

  • 在浏览器获取的内容与什么 php 正在获取?任何字节差异?不同的内容?请记住,仅仅因为两个实例中的 url 相同并不意味着服务器将向两者发送相同的内容。
  • 5.4K 和 4.3K 所以它似乎是不同的数据......这种方法在不同的域上工作了前 90 次左右,这是第一个有这个问题的域。
  • 检查您的浏览器是否没有以静默方式将其保存为其他文件,例如 .bmp。 IE 因默默地丢弃此类数据而臭名昭著,因为它认为自己比您更聪明。
  • 使用我上面提供的链接很容易查看file_get_contents() 返回的数据。有没有办法验证它或确定问题所在。我什至无法在像 inkscape 这样的图像编辑器中打开该文件。

标签: php image file-get-contents


【解决方案1】:

如果您查看可以从浏览器中显示的图像中获得的标题,您会注意到以下重要的“事实”:

HTTP/1.1 200 OK 
Content-Type: image/x-icon 
Content-Length: 4397 
Connection: keep-alive 
Date: Mon, 06 Oct 2014 23:36:51 GMT 

Content-Encoding: gzip

Expires: Sun, 17-Jan-2038 19:14:07 GMT 
Last-Modified: Mon, 06 Oct 2014 23:35:34 GMT 
...

含义:它不是一个普通的图标,它是 gzip 压缩的。因此,当您尝试使用file_get_contents 下载它时,您将收到一些不是图标的字符串。 (浏览器支持开箱即用的 gzip 压缩文件,因为它 常用于压缩数据)

您可以使用以下方法下载 gzip 文件并将其存储为“纯文件”:

function download_content_gzip($url, $out){
  //fetch compressed file
  $tmp = file_get_contents($url);
  file_put_contents("tmp.gzip", $tmp);

  $buffer_size = 4096; // read 4kb at a time

  // Open files (in binary mode)
  $file = gzopen("tmp.gzip", 'rb');
  $out_file = fopen($out, 'wb');

  while(!gzeof($file)) {
     fwrite($out_file, gzread($file, $buffer_size));
  }

  // close
  fclose($out_file);
  gzclose($file);
}

这可以优化以避免临时文件名,但这是你的功课:-)

用法:

download_content_gzip("http://d36xtkk24g8jdx.cloudfront.net/bluebar/e2609e5/images/ico/favicon.ico", "instagram.ico");

最后,您的“instagram.ico”将成为有效文件。

注意:gzopen() 也可以读取未压缩的文件。因此,如果您有多个来源并且不想确定实际的 content-Type,则此方法适用于两种情况。


对于 PHP > 5.4,它可以写成几行:

$content = file_get_contents_gzip("http://d36xtkk24g8jdx.cloudfront.net/bluebar/e2609e5/images/ico/favicon.ico");
file_put_contents("result.ico", $content);

function file_get_contents_gzip($url){
   return gzdecode(file_get_contents($url));
}

对于较旧的 PHP 版本 > 4.0.1,应该 gcuncompress() 用于字符串 - 但它似乎失败了。

这个小解决方法到目前为止有效:

$content = file_get_contents_gzip("http://d36xtkk24g8jdx.cloudfront.net/bluebar/e2609e5/images/ico/favicon.ico");
file_put_contents("result.ico", $content);

function file_get_contents_gzip($url){
   return gzdecode(file_get_contents($url));
}

function gzdecode($string) { // no support for 2nd argument
   return file_get_contents('compress.zlib://data:who/cares;base64,'. base64_encode($string));
}

【讨论】: