【发布时间】:2011-02-04 18:54:04
【问题描述】:
我有一个 PHP 脚本,我将 JPEG 图像上传到该脚本(通过 HTML 表单)。你可以看到代码here,但我会尝试在这篇文章中展示相关部分。表单声明如下:
<form action="adm_addphoto.php" method="POST" enctype="multipart/form-data" name="myform">
MAX_FILE_SIZE 表单域设置为 5MB:
<input type="hidden" name="MAX_FILE_SIZE" value=5242880>
我要上传的图片大小约为 3MB。
上传后,我将图像文件转换为 GD jpeg:
$filename = $_FILES['file']['tmp_name'];
$myImage = imagecreatefromjpeg($filename);
有时上传工作正常,有时imagecreatefromjpeg 会发出有关 JPEG 已损坏的警告。例如(为便于阅读添加了换行符):
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]:
gd-jpeg, libjpeg: recoverable error: Corrupt JPEG data:
47 extraneous bytes before marker 0xd9 in
/path/adm_addphoto.php on line 97
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]:
'/tmp/phpwlSS9x' is not a valid JPEG file in
/path/adm_addphoto.php on line 97
问题是,这不会可靠地发生。也就是说,如果我连续多次尝试相同的图像,有时会成功上传,有时会出现错误。在导致错误的尝试中,错误消息的细节也会有所不同。 (对于产生上述消息的特定照片,“无关字节”的数量有时是 47,有时是 20,有时是 68。)
什么可能导致文件在某些尝试中损坏,但在其他尝试中却没有?
PS。我知道有一个 ini 设置告诉 GD 努力处理损坏的 JPEG。但这不是重点,我想知道为什么上传的结果不一致。
PPS。以下是一些可能相关的 PHP ini 设置的值:
memory_limit .......... 128M
post_max_size ......... 8M
file_uploads .......... On
max_file_uploads ...... 20
upload_max_filesize ... 128M
upload_tmp_dir ........ no value
更新:我添加了代码以在文件上传后回显文件的大小和 MD5 校验和。大小始终是正确的文件大小(我的本地文件副本的大小)。但是,MD5 在尝试之间会有所不同。当 MD5 正确(与我的本地副本的 MD5 匹配)时,没有错误消息。当出现错误消息时,MD5 总是与预期不同。此外,这只是一种感知差异,但昨晚发生的错误似乎比今天早上更频繁——今天早上只有少数转移导致了错误。
这里有一些“糟糕”的上传(奇怪的是,有几个上传的 MD5 校验和与预期不同,但没有产生错误):
Correct MD5: f7b9587f39c7332e62a08adf34cefbd0
-----------------------------------------------------------------
38 extraneous bytes: 2a28c46079071d9d2e2fd49865b35d59
ce1c69f798953b201dcc35f85f3b29b4
b013a0428a71adff674a46e92372d46b
71 extraneous bytes: a271928f3559b6deaa19804704b5bcb3
92 extraneous bytes: cab2a10ad8535addaca3b19bcb607a30
premature end of data segment: 4514d39db1d94ab691d6da26c0832cdb
No error (!): 83b2e3624ddcfdeb3efc10be81631916
07d0a97b21d423fdeb4c6f88d76f8cd3
更新:回应 Andre 和 Pekka:以下是同一张图片的两个版本的链接。 This one 是图像的原始副本,存储在我的机器上;我以通常将文件上传到我的虚拟主机的方式上传它,即我使用了 FTP 客户端。 This one 是同一张图片,使用我的脚本上传(但添加了一行以使用move_uploaded_file() 将其移动到该位置)。该上传的错误消息是“损坏的 JPEG 数据:30 个无关字节......”。您会注意到图像的底部看起来不正确。对于图片尺寸过大,我深表歉意,但我只能举例说明给我带来问题的图片类型。
- 我应该明确指出,这与我用于上述 MD5 校验和的图像不同。我没想过要使用同一张图片。
更新:使用上面链接的两个图像,我发现了两个文件之间的差异。有两个 32 字节的序列在一个图像中与另一个不同。这些文件在其他方面是相同的。
n.b. the first character is numbered as character 1, not character 0
n.b. 2116624 and 2493456 are both 16 modulo 32.
The difference between them is 368 * 1024.
character 2116624 through line 2116655 (32 characters):
original image:
3c bc 20 19 eb 93 cd 34 db 93 68 7c 8d 5e 37 d4
d3 84 91 70 7e 7c 82 3e e9 e8 3d eb 2e ff 00 ce
bad image:
89 c9 54 a6 e5 3d f4 fc 8e 7f 68 d5 47 14 41 f6
55 11 7d a6 55 24 a8 e0 f7 a8 a4 43 06 18 c2 c1
character 2493456 through character 2493487 (32 characters):
original image:
3d a4 61 37 19 75 63 2e 51 62 ca 07 e0 9e 49 35
5d 65 8d 22 01 7f 5e b4 a7 19 3a 7a ef 72 1c e3
bad image:
4f 99 26 39 6a db d9 cd 3e 5b ec 63 46 3c b4 ef
2d b6 30 35 0f 12 a1 b6 9a 11 68 1a 69 07 0c 49
【问题讨论】:
-
您是否从日志条目中获得了这些错误消息?谁在上传?
-
我正在上传。这些错误是输出到浏览器的,因为我正在尝试调试问题,所以我启用了错误报告。
-
只是为了确定,您是否只有一个网络服务器,所以只有一个 php/gd 配置?
-
查看本地 JPEG 文件的前几个字节和上传的文件可能会有所帮助。 JPEG-magic-number 之前似乎出现了一些意外字节。
-
是的,你能举一些实际的例子吗?这可能是格式问题
标签: php file-upload