[英]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.