Файлы JPEG, загруженные в сценарий PHP, приходят поврежденными, но не всегда

У меня есть PHP-скрипт, в который я загружаю изображения в формате JPEG (через HTML-форму). Вы можете увидеть код здесь , но я постараюсь представить соответствующие части в этом посте. Форма объявлена ​​так:

В поле формы MAX_FILE_SIZE установлено значение 5 МБ:


Изображения, которые я хочу загрузить, имеют размер около 3 МБ.

После загрузки я включаю файл изображения в 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

ОБНОВЛЕНИЕ: В ответ Андре и Пекке: Вот ссылки на две версии одного и того же изображения. Этот является исходной копией изображения, хранящейся на моей машине; Я загрузил его так, как обычно загружаю файлы на свой хостинг, то есть я использовал FTP-клиент. Это то же изображение, загруженное с помощью моего скрипта (но с добавленной строкой, чтобы переместить его в это место с помощью 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

9
задан Hammerite 7 February 2011 в 10:17
поделиться