После погони за соответствующим кодом до _gettemp в реализации libc во FreeBSD 7, я не могу понять, как содержимое файла tmp_name
может быть недопустимым. (Чтобы отследить это, вы можете скачать копию PHP 5.2.8 и прочитать в main/rfc1867.c
- строка 1018 вызывает в main/php_open_temporary_file.c
функцию, начинающуюся со строки 227, которая выполняет основную работу в функции, начинающейся со строки 97, который, однако, по сути является просто оболочкой для mkstemp в вашей системе, который можно найти в реализации libc * FreeBSD в строке 66 (связанный), в которой используется _gettemp (то же, что и выше) на самом деле генерировать случайное имя файла. Однако на странице man для mkstemp в разделе BUGS упоминается, что arc4random()
функция не является реентерабельной. Это может что 2 одновременных запроса входят в критическую секцию кода и возвращают один и тот же tmp_name
- я слишком мало знаю о том, как Apache работает с mod_php или php-cgi, чтобы комментировать там (хотя использование FastCGI / php-cgi может работать - я могу ' в настоящее время это успешно комментируется).
Однако, стремясь к простейшему решению, если вы не совсем чувствуете, что файл tmp_name
является недействительным, но вместо этого сталкиваются с другими загруженными файлами (например, если использовать часть имени файла tmp_name в качестве единственного источника уникальности) в сохраненном имени файла) вы можете столкнуться с коллизиями из-за дня рождения парадокса . В другом вопросе вы упоминаете о необходимости перемещения около 5 000 000 файлов, а в еще одном вопросе вы упоминаете о получении 30-40 тыс. Загрузок в день. Это кажется мне главной ситуацией для столкновения с парадоксом дня рождения. В справочной странице mktemp упоминается, что (если используется шесть «X», как в PHP), существует 56 800 235 584 возможных имен файлов (62 ** 6 или 62 ** n, где n = количество «X» и т. Д.) , Однако, учитывая, что у вас более 5 миллионов файлов, вероятность коллизии составляет приблизительно 100% (другая эвристика предполагает, что вы уже испытали порядка 220 коллизий, если ((файлы * (files-1)) / 2) / (62 ** 6) означает что угодно, где files = 5 000 000). Если с этой проблемой вы столкнулись (вероятно, , если не добавляет дополнительной энтропии к сгенерированному загруженному имени файла), вы можете попробовать что-то вроде move_uploaded_file($file['tmp_name'], UPLOADS.sha1(mt_rand().$file['tmp_name']).strrchr($file['name'], '.'))
- идея состоит в том, чтобы добавить больше случайности к случайному имени файла, предотвращение столкновений. Альтернативой может быть добавление еще двух 'X' к строке 134 main/php_open_temporary_file.c
и перекомпиляция.