【问题标题】:PHP File Upload corrupted JPEGSPHP 文件上传损坏的 JPEGS
【发布时间】:2011-07-10 23:07:38
【问题描述】:

我们有一个使用 Andrew Valums ajax 文件上传器的网络应用程序,如果我们一次启动 5 到 10 个图像上传,那么通常至少 2 或 3 个不会导致相同的 gd 错误“损坏 JPEG 数据”

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

当我对它们进行 BinDiffed 时,我看到一个一致的模式,损坏总是 64 字节块,虽然损坏块之间的距离不是恒定的,但数字 4356 出现了很多。

我真的认为我们可以排除 Internet,因为使用 TCP 进行错误检查和重新传输非常可靠,而且浏览器版本之间似乎没有区别,或者我是否关闭了防病毒和防火墙。

所以我要选择 Apache / PHP 的配置?

【问题讨论】:

  • 我在这里可能帮不了你,但这是个好问题。干得好。
  • 这可能不是一个解决方案,但您是否尝试过不同的网络服务器?总是有nginx 和lighttpd。
  • 是的,我确信不同的服务器会解决这个问题,因为它只在新服务器上启动,这就是为什么我觉得这是一个 Apache/PHP 配置问题。
  • 当我今天有时间时,我可能会遵循这个线程bugs.php.net/bug.php?id=19263 中的想法。我的另一个想法是在 php 从 tmp 复制数据之前检查数据是否损坏。
  • 上面论坛帖子中的想法没有帮助。我还尝试禁用允许并发上传的 session_write_close(),没有骰子。我还将 JSUploader 从 XMLHttpRequest() 上传切换到较旧的 iframe 表单发布方法,结果仍然相同。

标签: php file-upload jpeg corruption


【解决方案1】:

一些相机会在文件中附加一些数据,这些数据会被错误地解释(很可能是在标题中进行字符编码)。

我找到的一个解决方案是像这样以二进制模式读取文件

$fh = fopen('test.jpg', 'rb');
$str = '';
while($fh !== false && !feof($fh)){
    $str .= fread($fh, 1024);
}

$test = @imagecreatefromstring($str);

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

【讨论】:

    【解决方案2】:

    好吧,我认为问题在于 jpeg-header 数据,据我所知 PHP 与它无关,我认为问题在于您的文件上传器,也许您缺少一些配置.

    【讨论】:

    • 问题是 jpeg-header 数据,但是我不同意这是 JS 上传器的错,甚至是上传器的 PHP 脚本端,因为我们在两个单独的服务器上运行它(Godaddy , 和笔记本电脑上的 localhost) 并且无法重现错误,它只发生在我们的新生产服务器上。
    • 如果你在哪里,我会测试简单的上传脚本以确保服务器正常工作。你可能想通过手动创建 jpeg-header 来解决这个问题(我不是说这是正确的做法),看看这个:link
    【解决方案3】:

    嗯 - 64 字节损坏?...或者您的意思是 64 位?

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

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

    阅读此处了解有关此问题的更多信息:

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

    【讨论】:

      【解决方案4】:

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

      ini_set ('gd.jpeg_ignore_warning', 1);
      

      【讨论】:

        【解决方案5】:

        我在使用 GoDaddy 托管时遇到了这个问题。 我使用他们的 cPanel 界面在 GoDaddy 上创建了数据库。它被创建为“拉丁排序规则”(或类似的东西)。开发服务器上的数据库是 UTF8。我已经尝试了此页面上的所有解决方案,但无济于事。然后我将数据库转换为 UTF8,它工作。

        数据库编码不应该影响 BLOB 数据(或者我认为)。据我所知,BLOB 代表 BINARY 大型对象(某物...)!

        此外,奇怪的是,数据从开发服务器复制到生产服务器,而数据库仍然是“拉丁”,并且根本没有损坏。只有在插入新图像时才会出现问题。所以我猜图像数据被作为文本数据提供给 MySQL,我认为有一种方法(使用 SQL 时)插入二进制数据,但我没有遵循它。

        编辑:刚刚看了一下 MySQL 导出脚本,这里是:
        插入 ... 值 (..., _binary 0xFFD8FF ...

        无论如何,希望这会对某人有所帮助。 OP没有说明是什么解决了他的问题......

        【讨论】:

          猜你喜欢
          • 2017-08-29
          • 1970-01-01
          • 2020-09-27
          • 1970-01-01
          • 2017-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-07
          相关资源
          最近更新 更多