簡體   English   中英

PHP:如果我強制下載圖像已損壞

[英]PHP: image corrupted if I force the download

使用簡單的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可以正常工作。 text.png的MD5校驗和與原始圖像相等。

這是test.png的十六進制代碼。

在此處輸入圖片說明

這是下載后損壞文件的十六進制代碼:

在此處輸入圖片說明

如您所見,開頭有2個額外的字節。 如果刪除它們,文件將恢復正常工作。

我附上了Wireshark的屏幕(如您所見,這不是瀏覽器問題):

在此處輸入圖片說明

我該如何解決?

服務器是帶有PHP-5.6的Ubuntu 16.04(是的,由於roundcube的兼容性問題,我將其從7.0降級到5.6)

更新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();
?>

如果我使用/wp-admin/admin-ajax.php?action=frontend_download_doc調用downlod_test,則會添加2個額外的字節。 如果我直接調用它(通過刪除注釋),它將起作用。

因此,現在的問題是:如何去除wordpress添加的這些字節?

為了幫助您找到不需要的空格,您可以使用get_included_files()跟蹤加載的文件。 此外, 回溯還可能使您的腳本無法正常工作。

在許多情況下,它將來自關閉文件末尾的PHP標記。 由於它們是可選的,因此建議不要使用它們。

找到該空白位置的文件后,只需加載您喜歡的文本編輯器並將其刪除(您可能需要啟用編輯器的“ 顯示隱藏的字符”功能)。

PS我知道這可能是簡化的代碼來說明問題,但您可能想嘗試一下readfile()

$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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM