Я выделил ошибку в 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
Я обнаружил, что когда содержимое просматривается в браузере, появляются реальные данные.
Смотри вывод выше ВОТ если хочешь.
Однако сохраненный файл не выглядит как .ico на моем клиенте или сервере.
Несмотря на правильное расширение файла, SO не позволит мне загрузить его, так как он корректно определяется как не файл изображения.
Правильный файл легко получить, вставив ссылку в URL браузера.
http://d36xtkk24g8jdx.cloudfront.net/bluebar/e2609e5/images/ico/favicon.ico
и просто используя save as
скачать его.
Однако мне нужна работающая автоматизированная версия, и я не знаю, как ее устранить.
Я подтвердил, что file_get_contents
действительно получает контент и file_put_contents
на самом деле сохраняет содержимое.
Тем не менее, это не правильный файл изображения.
Если вы посмотрите на заголовок, который вы можете получить из изображения, отображаемого в браузере, вы заметите следующий важный «факт»:
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
...
Значение: это не обычная иконка, она разархивирована. Итак, когда вы пытаетесь скачать его с помощью file_get_contents
Вы получите строку, которая НЕ является иконкой. (Браузеры поддерживают сжатые файлы из коробки, потому что его
часто используется для сжатия данных)
Вы можете использовать следующий метод, чтобы загрузить файл gziped и сохранить его как обычный файл:
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()
может читать несжатые файлы. Поэтому, если у вас есть несколько источников и вы не хотите определять фактический тип содержимого, этот метод будет работать в обоих случаях.
Для 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));
}
Других решений пока нет …