PHP: изображение повреждено, если я заставляю загрузку

У меня странное поведение с простым кодом PHP. Когда я пытаюсь принудительно загрузить или распечатать изображение, используя правильный тип содержимого, выходной файл поврежден.

Кажется, что веб-сервер (Apache) добавляет два байта (0x20 и 0x0A) в начале файла.

Это код:

$file = "image.png";
$image = file_get_contents($file);

// Test
file_put_contents("test.png", $image);

// Download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));

echo $image;

Я использую тот же код на других сайтах, размещенных на том же сервере без проблем.

Проблема только в загрузке только потому, что test.png работает правильно. Контрольная сумма MD5 text.png и исходного изображения равны.

Это шестнадцатеричный код test.png.

введите описание изображения здесь

И это шестнадцатеричный код поврежденного файла после загрузки:

введите описание изображения здесь

Как видите, в начале есть 2 дополнительных байта. Если я удаляю их, файл возвращается к работе должным образом.

Я прикрепляю экран Wireshark (как вы можете видеть, это не проблема браузера):

введите описание изображения здесь

Как я могу это исправить?

Сервер Ubuntu 16.04 с PHP-5.6 (да, я сделал понижение с 7.0 до 5.6 для проблем совместимости с roundcube)

ОБНОВЛЕНИЕ 1: Я пытаюсь найти, если где-то в файле есть пробел + перевод строки

ОБНОВЛЕНИЕ 2:

Прежде всего: спасибо.

Код является частью плагина WordPress, и загрузка вызывается с использованием системы AJAX. Я написал простой тест плагинов:

<?php
/*
Plugin Name: Test
Plugin URI: http://www.google.com
Description: Test
Author: Anon
Version: 4.0
*/
function downlod_test() {
echo "test";
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=prova.html');
die();
}
function iopman_shared_download_doc_ajax() {
downlod_test();
}
add_action('wp_ajax_frontend_download_doc', 'iopman_shared_download_doc_ajax');

//downlod_test();
?>

Если я вызываю downlod_test с /wp-admin/admin-ajax.php?action=frontend_download_doc, он добавляет 2 дополнительных байта. Если я позвоню прямо (удалив комментарии), это сработает.

Итак, проблема сейчас в следующем: как удалить эти байты, которые добавляет WordPress?

0

Решение

Чтобы помочь вам найти этот ненужный пробел, вы можете отслеживать загруженные файлы с get_included_files (). Кроме того, трассировка также может пролить свет на то, что делает ваш скрипт.

Во многих случаях это происходит из-за закрытия тегов PHP в конце файла. Поскольку они не являются обязательными, рекомендуется просто не использовать их.

После того, как вы найдете файл, в котором находится этот пробел, вам нужно всего лишь загрузить его в ваш любимый текстовый редактор и удалить их (вам может потребоваться включить ваш редактор Показать скрытые символы особенность).

Постскриптум Я понимаю, что это, вероятно, упрощенный код, чтобы проиллюстрировать проблему, но вы можете дать ReadFile () попытка

1

Другие решения

$file = "image.png";
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header("Content-Encoding: gzip");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header("Content-Length: " . filesize($file));
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
ob_get_clean();
readfile($file);
exit;
0

По вопросам рекламы [email protected]