PHP文件上传导致JPEG图像损坏

3
我们有一个使用Andrew Valums的ajax文件上传器的Web应用程序,如果我们同时启动5-10个图像上传,往往至少有2或3个会导致相同的gd错误“Corrupt JPEG data”。
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]:
         gd-jpeg, libjpeg: recoverable error: Corrupt JPEG data:
         47 extraneous bytes before marker 0xd9 in .... 

然而,在我们的旧测试服务器或本地开发环境中并没有出现这种情况,只有在我们的新生产服务器上才有。
服务器上的文件大小与我本地机器上的原始文件大小相同,因此它完成了上传,但我认为数据被服务器损坏了。
我可以通过删除它们并重新上传或通过FTP手动上传来“修复”损坏的文件。
我们在Godaddy上共享主机,并在一个新盒子上(由我设置,所以可能解释了很多问题:)CentOS 5.5+,Apache 2.2.3,PHP 5.2.10)开始遇到这个问题。
您可以在此处查看一些好的和坏的示例图片。http://174.127.115.220/temp/pics.zip 当我对它们进行BinDiff时,我看到了一致的模式,损坏总是64字节块,虽然损坏块之间的距离不是恒定的,但数字4356经常出现。
我真的认为我们可以排除互联网作为错误检查和TCP的重传非常可靠,进一步的是似乎没有浏览器版本之间的区别,或者如果我关闭反病毒和防火墙。
所以我正在选择 Apache / PHP 的配置?

1
我可能无法在这里帮助你,但这是一个好问题。做得好。 - rockerest
这可能不是一个解决方案,但你尝试过不同的网络服务器了吗?总有nginxlighttpd可供选择。 - Blender
是的,我确定换一个不同的服务器会解决这个问题,因为它只在新服务器上开始出现,所以我觉得这是一个 Apache/PHP 配置问题。 - dave.zap
今天如果有时间的话,我可能会跟进这个帖子中的想法 https://bugs.php.net/bug.php?id=19263。我的另一个想法是在 PHP 从 tmp 复制数据之前检查数据是否损坏。 - dave.zap
上面论坛帖子中的想法没有帮助。我还尝试禁用session_write_close()以允许并发上传,但没有效果。我还将JSUploader从XMLHttpRequest()上传切换到旧的iframe表单提交方法,结果仍然相同。 - dave.zap
感谢您写下这篇文章,我将尝试您提到的一些故障排除方法--我认为我在engineyard上使用trinidad和nginx时遇到了相同的问题,但在我的本地机器上没有出现这种情况!https://dev59.com/G2DVa4cB1Zd3GeqPcE41 - Peter Ehrlich
5个回答

2
一些相机会在文件中附加一些数据,这些数据可能由于标头内的字符编码问题而被错误地解释。我找到的解决方案是以二进制模式读取文件,如下所示。
$fh = fopen('test.jpg', 'rb');
$str = '';
while($fh !== false && !feof($fh)){
    $str .= fread($fh, 1024);
}

$test = @imagecreatefromstring($str);

imagepng($test,'save.png');

1

嗯,我认为问题在于JPEG头数据,据我所知PHP无法处理它,我认为问题出在你的文件上传器上,也许有一些你忽略了的配置。


问题在于jpeg头数据,然而我不同意这是JS上传程序的错误,甚至不是上传程序的PHP脚本方面的错误,因为我们在两个不同的服务器上运行它(Godaddy和笔记本电脑上的本地主机),并且无法再现此错误,它只在我们的新生产服务器上出现。 - dave.zap
如果我是你,我会测试简单的上传脚本,以确保服务器工作正常。你可能想通过手动创建JPEG头来解决这个问题(我不是说这是正确的做法),可以参考这个链接:link - Pezhvak IMV

0

这可以通过以下方式解决:

ini_set ('gd.jpeg_ignore_warning', 1);

0
我在使用GoDaddy主机时遇到了问题。 我使用他们的cPanel界面在GoDaddy上创建了数据库。它被创建为“拉丁排序”(或类似的东西)。开发服务器上的数据库是UTF8。我尝试了这个页面上的所有解决方案,但都没有成功。然后我将数据库转换为UTF8,它就可以工作了。
数据库编码不应该影响BLOB数据(或者我认为不应该)。BLOB代表二进制大对象(某物...),据我所知!
另外,奇怪的是,当数据库仍然是“拉丁语”时,数据从开发服务器复制到生产服务器时并没有损坏。只有在插入新图像时才出现了问题。因此,我想图像数据被作为文本数据馈送到MySQL中,而我认为有一种方法(在使用SQL时)可以插入二进制数据,而我没有遵循它。
编辑:刚刚查看了MySQL导出脚本,这里是:
INSERT INTO ... VALUES (..., _binary 0xFFD8FF ...
无论如何,希望这能帮助到某人。原帖作者没有说明是什么解决了他的问题...

0

嗯——64字节的损坏?还是你指的是64位?

我建议问题实际上是由PHP脚本引起的。这里经常出现的问题是脚本将CRLF插入正在上传的数据流中,这是由于Window/*nix标准之间的差异造成的。

解决方案是强制php脚本以二进制模式上传(在php上传的所有fopen()命令中使用+b开关)。以二进制模式上传文本文件是安全的,因为至少您仍然可以看到数据。

阅读此处以获取有关此问题的更多信息:

http://us2.php.net/manual/en/function.fopen.php


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接