Как определить, загрузил ли пользователь файл больше, чем post_max_size?

Как мне обращаться с обработкой HTTP-загрузок, которая превышает значение post_max_size в разумной манере?

В моей конфигурации post_max_size на несколько МБ больше, чем upload_max_filesize У меня проблемы:
Если пользователь загружает файл, превышающий post_max_size

  • Массив _POST пуст
  • Массив _FILES пуст, и, конечно, никаких кодов ошибок в нем нет.
  • Никакая другая информация, какая форма сообщения, она доступна через эти средства.

Отчасти проблема заключается в том, что принимающий скрипт принимает различные действия в зависимости от содержимого 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 .