Как мне обращаться с обработкой HTTP-загрузок, которая превышает значение post_max_size
в разумной манере?
В моей конфигурации post_max_size
на несколько МБ больше, чем upload_max_filesize
У меня проблемы:
Если пользователь загружает файл, превышающий post_max_size
Отчасти проблема заключается в том, что принимающий скрипт принимает различные действия в зависимости от содержимого POST.
У меня есть доступ к переменным _SERVER
и вы можете узнать, что произошло, т.е. CONTENT_TYPE
, CONTENT_LENGTH
и REQUEST_METHOD
. Однако представляется весьма проблематичным делать догадки на основе этих данных.
MEMORY_LIMIT (установлено в 10 раз соответствующих размеров) и Apache LimitRequestBody (установлено на неограниченное количество), как установлено, не будут виноваты.
В настоящее время мне нелегко даже предоставить какие-либо значимые сообщения пользователю.
Есть ли способ сохранить данные какой-либо формы, чтобы лучше понять, что пошло не так? Я очень неохотно отошел от php.
Для простого исправления, которое не требует изменений на стороне сервера, я бы использовал API файлов HTML5, чтобы проверить размер файла перед загрузкой. Если он превышает известный предел, отмените загрузку. Я считаю, что что-то вроде этого будет работать:
function on_submit() { if (document.getElementById("upload").files[0].size > 666) { alert("File is too big."); return false; } return true; } <form onsubmit="return on_submit()"> <input id="upload" type="file" /> </form>
Очевидно, что это всего лишь скелет примера, и не каждый браузер поддерживает это. Но это не помешает использовать это, поскольку это может быть реализовано таким образом, чтобы оно изящно не превращалось в ничто для старых браузеров.
Конечно, это не решает проблему, но, по крайней мере, она будет поддерживать ряд ваших пользователей с минимальными усилиями. (И им даже не придется ждать завершения загрузки.)
–
В стороне, проверка $_SERVER['CONTENT_LENGTH']
сравнению с размером данных post и файла может помочь обнаружить, что что-то не удалось. Я думаю, что когда будет ошибка, она будет равна нулю, а $_POST
и $_FILES
будут пустыми.
По документации PHP :
Если размер пост-данных больше, чем post_max_size, суперглавы $ _POST и $ _FILES пустые. Это можно отслеживать различными способами, например, передавая переменную $ _GET скрипту, обрабатывающему данные, т. Е. <Form action = "edit.php? Обработан = 1">, а затем проверяет, является ли $ _GET ['обработанным "] задавать.
Если вам нужен лимит, увеличенный для определенного скрипта, вы можете попробовать ini_set ('post-max-size', $ size_needed) ;. Я не уверен, что он может быть переопределен в скрипте; этот предел, вероятно, существует, чтобы не дать вам делать то, что вы пытаетесь сделать.
Мне понравился ответ @Matthew, но мне нужна версия, которая проверяет наличие нескольких файлов для загрузки.
Это было мое решение:
function checkAttachmentsSize() { var total = 0; var count = 0; jQuery('input[type="file"]').each( function() { if (typeof this.files[0] != 'undefined') { total+= this.files[0].size; count++; } } ); var word = (count > 1) ? 's are' : ' is'; if (total > (uploadMax * 1000 * 1000)) { alert("The attachment file" + word + " too large to upload."); return false; } return true; }
И, для полноты, вот привязка функции к представленной форме:
jQuery(function($) { $("form").submit( function() { return checkAttachmentsSize(); } }); );
ЗАМЕТКА:
uploadMax – это переменная, которую я установил через php после вычисления максимального размера допустимой загрузки.
Вы можете решить это на стороне сервера, не прибегая к строке запроса. Просто сравните настройку * post_max_size * с ожидаемой длиной содержимого запроса. Следующий код – это то, как это делает Кохана.
public static function post_max_size_exceeded() { // Make sure the request method is POST if (Request::$initial->method() !== HTTP_Request::POST) return FALSE; // Get the post_max_size in bytes $max_bytes = Num::bytes(ini_get('post_max_size')); // Error occurred if method is POST, and content length is too long return (Arr::get($_SERVER, 'CONTENT_LENGTH') > $max_bytes); }
Возможно, вам придется вернуться к чему-то, что использует flash / silverlight и т. Д., Например: http://www.plupload.com/
Или посмотрите на Java-решение …
В основном что-то сломает загрузку в более управляемые (и возобновляемые) куски, а затем снова собирает их на стороне сервера.
Если ваша форма для отправки не имеет полей, отличных от поля ввода файла, то $ _POST должен быть пустым: файлы обрабатываются исключительно через $ _FILES. Очень странно, что $ _FILES будет пустым, если размер сообщения превышен – обработчики загрузки имеют конкретный код ошибки (1 / UPLOAD_ERR_INI_SIZE ), чтобы сообщить о таком состоянии. Также проверьте, что memory_limit
больше, чем upload_max_filesize.
Ваш веб-сервер также может блокировать загрузку, которая будет возникать до вызова PHP. В Apache он контролируется LimitRequestBody
.