我有一个PHP脚本,我上传JPEG图像(通过HTML表单).你可以在这里看到代码,但我会尝试在这篇文章中介绍相关部分.表单声明如下:
<form action="adm_addphoto.php" method="POST" enctype="multipart/form-data" name="myform">
Run Code Online (Sandbox Code Playgroud)
该MAX_FILE_SIZE表单字段设置为5MB:
<input type="hidden" name="MAX_FILE_SIZE" value=5242880>
Run Code Online (Sandbox Code Playgroud)
我要上传的图片大小约为3MB.
一旦上传,我将图像文件转换为GD jpeg:
$filename = $_FILES['file']['tmp_name'];
$myImage = imagecreatefromjpeg($filename);
Run Code Online (Sandbox Code Playgroud)
有时上传工作正常,有时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
Run Code Online (Sandbox Code Playgroud)
问题是,这不可能发生.也就是说,如果我连续多次尝试相同的图像,有时它会成功上传,有时会出现错误.在导致错误的尝试中,错误消息的细节也会有所不同.(使用产生上述消息的特定照片,"无关字节"的数量有时为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
Run Code Online (Sandbox Code Playgroud)
更新:我添加了代码,以便在文件上传后回显文件的大小和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
Run Code Online (Sandbox Code Playgroud)
更新:回应安德烈和佩卡:以下是相同图片的两个版本的链接.这是存储在我的机器上的图像的原始副本; 我上传的方式是我经常将文件上传到我的网站主机,即我使用的是FTP客户端.这是使用我的脚本上传的相同图像(但添加了一行以将其移动到该位置move_uploaded_file()).该上传的错误消息是"Corrupt JPEG data:30 extraneous bytes ...".您会注意到图像的底部显示不正确.我为大尺寸的图像道歉,但我只能使用给我带来问题的图像类型的例子.
更新:使用我上面链接的两个图像,我发现了两个文件之间的差异.有两个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
Run Code Online (Sandbox Code Playgroud)