Связь между phps memory_limit, upload_max_filesize и post_max_filesize
Нижняя линия:
Мне нужно беспокоиться о настройке post_max_filesize
→ memory_limit
?
Подробнее:
Этот ответ предполагает, что загруженные файлы не должны вписываться в phps memory_limit. php docs показывают, что весь пост должен соответствовать пределу памяти phps.
Я нахожу, что документы удивительны, и я надеюсь, что кто-то сможет это сделать. Например, возьмите следующие конфигурации php:
; config A
memory_limit = 50M
upload_max_filesize = 100M
post_max_filesize = 1000M
max_file_uploads = 10
и
; config B
memory_limit = 50M
upload_max_filesize = 10M
post_max_filesize = 1000M
max_file_uploads = 100
В этих конфигурациях Id ожидает, что сможет:
- загружать файлы 10x100mb на сервер A,
- и 100x10mb файлы на сервер B.
Я также ожидал бы, что:
- Работа с любыми один из 10 файлов, загруженных на сервер A, является проблемой (100Ms файла в сумке 50M...).
- Работа с любыми 1 из 100 файлов, загруженных на сервер B, в порядке (10 и 50).
Во время экспериментов с менее круглыми, но эквивалентно связанными числами, Ive нашло эти ожидания справедливыми.
Этот опыт заставил бы меня сказать, что "как правило, memory_limit должен быть больше, чем upload_max_filesize
"; вместо этого php docs говорит:
вообще говоря, memory_limit должен быть больше post_max_size
.
Почему и что происходит, если это не так?
Когда мой PHP-код выполняется, я не вижу никаких доказательств того, что все опубликованные файлы находятся в памяти. Мне кажется, что все, что я получил, это массив $_FILES путей к файлам, найденным исключительно на диске. Является ли php удерживанием всего сообщения в памяти в какой-то момент до моей способности исследовать окружающую среду? Мне нужно беспокоиться о настройке post_max_filesize
→ memory_limit
?
В сторону:
Нарушение правила вручную не приводит к грубо разбитому серверу (w/php5.3 apache2.2 debian 6).
Ответы
Ответ 1
PHP будет принимать загруженные файлы, индивидуально меньшие, чем upload_max_filesize
, и вместе принимать меньше, чем post_max_size
байтов. Документация PHP неверна в отношении memory_limit
, которая не должна содержать размещенное содержимое файла.
Следующая конфигурация работает как с модулем Apache2, так и с CGI и принимает файлы размером менее 1G.
upload_max_filesize = 1G
post_max_size = 1G
memory_limit = 32M
Ответ 2
Нужно ли беспокоиться о установка post_max_filesize → memory_limit?
Только если вы планируете читать весь файл в памяти, а файл, который вы читаете, больше, чем пространство, которое вы выделили для PHP (т.е. memory_limit
), и в этом случае у вас не хватит памяти.
Ответ 3
Мой собственный опыт заключается в том, что вы должны иметь memory_limit выше, чем post_max_size и upload_max_size.
Post_max_size относится ко всей полноте данных POSTed. Сюда входят любые поля формы, которые могут быть включены в файл. Upload_max_size - это самый большой допустимый размер файла, который может быть в этой загрузке.
Например. с post_max_size 10mb и upload_max_size 1mb, вы можете загрузить 9 файлов, каждый размером 1 МБ, Почему 9 файлов? потому что часть данных POST - это метаданные файла - имя файла, mimetype, размер файла и т.д. Это занимает некоторое место, поэтому ваши 9 файлов будут занимать соответственно 9,01 мегабайта. Остаток 0.99 слишком мал для другого файла, поэтому вы не можете загрузить это 10-е, даже если оно соответствует пределу upload_max_size.
Что касается memory_limit, у вас не должно быть достаточно "комнаты" для загруженных файлов, вы должны помнить, что это ограничение относится к script в целом. Memory_limit из 10mb позволит загружать только файл размером 9 мегабайт, потому что сам PHP и все связанные с ним коды и библиотеки будут всасывать (скажем) 1 мегабайт уже.
Несмотря на то, что файлы не хранятся в памяти - они как можно скорее выгружаются в временные файлы, они передаются в PHP из Apache через STDIN. PHP должен читать файлы из этого потока и копировать их во временные файлы, которые вы используете в разделе ['tmp_name']
массива $_FILES.
По какой-то причине PHP, по-видимому, в основном делает "file_get_contents()" и разрывает файлы навалом, вместо того, чтобы делать копию потокового типа. Следовательно, требуется memory_limit, который превышает максимально допустимый размер файла.