Почему $ _FILES будет пустым при загрузке файлов в PHP?

123

У меня есть WampServer 2, установленный на моем компьютере под управлением Windows 7. Я использую Apache 2.2.11 и PHP 5.2.11. Когда я пытаюсь загрузить любой файл из формы, он, кажется, загружается, но в PHP массив $_FILES пуст. В папке c:\wamp\tmp нет файла. Я настроил php.ini, чтобы разрешить загрузку файлов и т.д. Папка tmp имеет права чтения/записи для текущего пользователя. Я в тупике.

HTML:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form enctype="multipart/form-data" action="vanilla-upload.php" method="POST">
        Choose a file to upload: <input name="uploadedfile" type="file" /><br />
        <input type="submit" value="Upload File" />
    </form>
</body>
</html>

PHP:

<?php
echo 'file count=', count($_FILES),"\n";
var_dump($_FILES);
echo "\n";
?>
  • 2
    Вы проверили журналы ошибок?
  • 0
    Я уверен, что есть что-то глупое, что вы пропускаете. Например, вы обязательно должны иметь код в vanilla-upload.php ?
Показать ещё 1 комментарий
Теги:
file-upload

20 ответов

14
Лучший ответ

Спасибо всем за разные ответы. Все это очень полезно. Ответ оказался чем-то очень странным. Оказывается, PHP 5.2.11 не нравится следующее:

post_max_size = 2G

или

post_max_size = 2048M

Если я изменил его на 2047M, загрузка будет работать.

  • 17
    Обратите внимание, что такое высокое значение является уязвимостью к атакам вне пространства / ddos. Просто добавьте это, чтобы люди знали об этом слишком сильно, когда они пытаются скопировать и вставить ваше решение. В любом случае, 2 гигабайта потребуют слишком большого времени загрузки.
  • 0
    Уже не слишком большой. У нас есть клиенты, которые загружают файлы в диапазоне 1-3G довольно регулярно. Поскольку они загружают файлы на свои собственные серверы и являются серверами, внесенными в белый список IP-адресов, обмен вполне нормален и является просто способом, позволяющим клиенту использовать свое оборудование так, как он хочет. Они оплачивают счета, без риска для безопасности, никаких проблем.
408

Вот контрольный список для загрузки файлов в PHP:

  1. Проверьте php.ini для:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • Вам может понадобиться использовать .htaccess или .user.ini если вы используете общий хостинг и не имеете доступа к php.ini.
    • Убедитесь, что вы редактируете правильный INI файл - используйте phpinfo() чтобы убедиться, что ваши настройки действительно применяются.
    • Также убедитесь, что вы не ошиблись в размерах - это должно быть 100M не 100MB.
  2. Убедитесь, что ваш <form> имеет enctype="multipart/form-data". Никакой другой тег не будет работать, это должен быть ваш тег FORM. Дважды проверьте правильность написания. Дважды проверьте, что multipart/form-data окружены прямыми цитатами, а не умными цитатами, вставленными из Word OR из блога веб-сайта (WordPress преобразует прямые кавычки в угловые кавычки!). Если у вас есть несколько форм на странице, убедитесь, что у них обоих есть этот атрибут. Введите их вручную или попробуйте ввести одинарные кавычки вручную.

  3. Убедитесь, что у вас нет двух полей входного файла с одним и тем же атрибутом name. Если вам нужно поддерживать несколько, поставьте квадратные скобки в конце имени:

    <input type="file" name="files[]">
    <input type="file" name="files[]">
    
  4. Убедитесь, что в ваших каталогах tmp и upload установлены правильные разрешения на чтение и запись. Временная папка загрузки указана в настройках PHP как upload_tmp_dir.

  5. Убедитесь, что в вашем каталоге назначения и каталогах tmp/upload нет пробелов.

  6. Убедитесь, что все <form> на вашей странице имеют </form> закрывающие теги.

  7. Убедитесь, что ваш тэг FORM имеет method="POST". Запросы GET не поддерживают загрузку данных по нескольким частям/формам.

  8. Убедитесь, что ваш тег ввода файла имеет атрибут NAME. Атрибут ID НЕ является достаточным! Атрибуты ID предназначены для использования в DOM, а не для полезных нагрузок POST.

  9. Убедитесь, что вы не используете Javascript для отключения поля <input type="file"> при отправке

  10. Убедитесь, что вы не вкладываете формы, такие как <form><form></form></form>

  11. Проверьте структуру HTML на наличие недопустимых/перекрывающихся тегов, таких как <div><form></div></form>

  12. Также убедитесь, что в загружаемом файле нет никаких буквенно-цифровых символов.

  13. Однажды я просто часами пытался понять, почему это случилось со мной внезапно. Оказалось, что я изменил некоторые настройки PHP в .htaccess, и одна из них (пока не уверена, какая именно) вызывала сбой при загрузке и $_FILES.

  14. Вы можете попытаться избежать подчеркивания (_) в атрибуте name="" тега <input>

  15. Попробуйте загрузить очень маленькие файлы, чтобы сузить вопрос о размере файла.

  16. Проверьте свободное место на диске. Хотя это очень редко, это упоминается в этом комментарии к странице PHP Manual:

    Если массив $ _FILES внезапно загадочным образом становится пустым, даже если ваша форма кажется правильной, вы должны проверить дисковое пространство, доступное для вашего раздела временной папки. В моей установке все загрузки файлов не прошли без предупреждения. После большого скрежета зубов я попытался освободить дополнительное пространство, после чего загрузка файлов неожиданно снова заработала.

  17. Убедитесь, что вы не отправляете форму через POST-запрос AJAX вместо обычного POST-запроса, который приводит к перезагрузке страницы. Я просмотрел все пункты в приведенном выше списке и, наконец, обнаружил, что причина, по которой моя переменная $ _FILES была пустой, заключалась в том, что я отправлял форму с помощью запроса AJAX POST. Я знаю, что есть методы для загрузки файлов с использованием ajax, но это может быть веской причиной, по которой ваш массив $ _FILES пуст.

Источник для некоторых из этих пунктов:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/

  • 1
    Это не относится к обсуждению, но у меня был хостинг-провайдер, чья политика брандмауэра была слишком строгой, что приводило к сбою загрузки.
  • 8
    Может быть, «принятый» ответ решил оригинальную статью, но этот ответ я нашел наиболее полезным. Если вы сомневаетесь, посмотрите на источник в браузере. Отметив каждый элемент в этом списке и проследив его в обратном направлении, я обнаружил свою ошибку в самом неожиданном месте. Если вы боретесь с подобной проблемой, поверьте мне, это, вероятно, не ошибка в Apache. ;)
Показать ещё 22 комментария
69

Что касается HTML, вы, похоже, правильно настроили эту часть. У вас уже есть enctype="multipart/form-data", который очень важен для формы.

Что касается настройки php.ini, иногда в системах существует несколько файлов php.ini. Убедитесь, что вы редактируете правильный. Я знаю, вы сказали, что настроили свой файл php.ini на загрузку файлов, но вы также установили, что ваши upload_max_filesize и post_max_size больше, чем файл, который вы пытаетесь загрузить? Таким образом, вы должны иметь:

file_uploads = On; sounds like you already did this
post_max_size = 8M; change this higher if needed
upload_max_filesize = 8M; change this higher if needed

Имеется ли в вашем каталоге: "c:\wamp\tmp" права на чтение и запись? Вы не забыли перезапустить Apache после внесения изменений php.ini?


  • 4
    +1: для перезапуска сервера Apache совет. Многие пользователи Windows забывают об этом.
28

Важно добавить enctype="multipart/form-data" к вашей форме, например

<form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>
  • 1
    Вот это да. Действительно этот ответ должен быть принят IMO.
5

Убедитесь, что ваш form имеет следующий атрибут enctype="multipart/form-data.

5

У меня такая же проблема, как и 2 часа, очень просто проверить нашу конфигурацию сервера в первую очередь.

Пример:

echo $upload_max_size = ini_get('upload_max_filesize');  
echo $post_max_size=ini_get('post_max_size');   

размер любого типа файла :20mb, но наш upload_max_size выше 20mb, но массив null. Ответ: наш post_max_size должен быть больше upload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M
5

Вот еще одна причина, по которой я нашел: При использовании JQuery Mobile и данных атрибута form-ajax устанавливается значение true, массив FILES будет пустым. Поэтому установите data-ajax в false.

  • 0
    Это решит точную проблему для меня !! БЛАГОДАРЮ ВАС!
3

Убедитесь, что ваш элемент ввода имеет атрибут 'name'. <input type="file" name="uploadedfile" />

Если это отсутствует, $_FILES будет пустым.

3

Я боролся с той же проблемой и тестировал все, не получая сообщений об ошибках, и ничто не казалось неправильным. У меня был error_reporting (E_ALL) Но вдруг я понял, что не проверял журнал Apache и вуаля! Существовала синтаксическая ошибка на script...! (отсутствует "}" )

Итак, хотя это что-то очевидное, чтобы быть проверенным, его можно забыть... В моем случае (linux) он находится по адресу:

/var/log/apache2/error.log
2

Проверьте свой php.ini для enable_post_data_reading = Вкл., потому что:

Отключение этой опции приводит к тому, что $_POST и $_FILES не заполняются. Единственный способ прочитать postdata будет затем через фреймворк потока php://. (...)

В http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading

2

Никто не упоминал об этом, но это помогло мне, и не многие места в сети упоминают об этом.

Убедитесь, что ваш php.ini устанавливает следующий ключ:

    upload_tmp_dir="/path/to/some/tmp/folder"

Вам нужно будет проверить свой веб-хост, если они хотят, чтобы вы использовали абсолютный путь к файлу сервера. Вы должны увидеть другие примеры каталогов в файле php.ini, чтобы определить это. Как только я его установил, я получил значения в объекте _FILES.

Наконец, убедитесь, что ваша папка tmp и везде, где вы перемещаете файлы, имеют правильные разрешения, чтобы их можно было прочитать и записать.

2

Другой возможный виновник - перенаправление Apache. В моем случае у меня был apache httpd.conf, настроенный для перенаправления определенных страниц на нашем сайте на http-версии и на другие страницы в https-версии страницы, если они еще не были. Страница, на которой у меня была форма с вводом файла, была одной из страниц, настроенных для принудительного ssl, но страница, обозначенная как действие формы, была настроена как http. Таким образом, страница отправит загрузку в ssl-версию страницы действий, но apache перенаправляет ее на http-версию страницы, а данные сообщения, включая загруженный файл, были потеряны.

2

Если вы пытаетесь загрузить массив файлов, вам может потребоваться увеличить max_file_uploads в php.ini, который по умолчанию установлен до 20

Примечание: max_file_uploads НЕ МОЖЕТ быть изменено за пределами php.ini. См. PHP "Ошибка" # 50684

1

Я столкнулся с той же проблемой и обнаружил, что именно моя IDE была частью проблемы. Я запускал отладчик непосредственно из среды IDE (PHPStorm) вместо того, чтобы просто использовать браузер напрямую. Инициализированный URL-адрес IDE был следующим:

"...localhost:63342/CB_Upload/index.php?_ijt=j2hcbacqepj87bvg66ncuohvne"

и просто используя:

"...localhost/CB_Upload/index.php"

работал отлично. Моя настройка - ПК /Windows 10/WAMPSERVER 3.0.6 64bit

  • 0
    То же самое и здесь, я бегал кругами целый час! Спасибо
0

Если вы используете JQuery Mobile

Использование многочастной формы с вводом файла не поддерживается Ajax. В этом случае вы должны украсить родительскую форму data-ajax = "false", чтобы форма была правильно отправлена ​​на сервер.

<form action="upload.php" method="post" enctype="multipart/form-data"  data-ajax="false">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>
0

У меня тоже были проблемы с пустым значением $_FILES. В приведенном выше контрольном списке не упоминаются MultiViews в .htaccess, httpd.conf или httpd-vhost.conf.

Если у вас есть MultiViews, установленный в директиве опций для вашего каталога, содержащего веб-сайт, $_FILES будет пустым, даже если заголовок Content-Length, если вы покажете, что загруженный файл.

0

Я был пуст $_FILES, потому что после <form enctype="multipart/form-data" method="post"> я поставил

</div>
<div style="clear:both"></div>

Начальный код был похож на

<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
<form enctype="multipart/form-data" method="post">
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>

Я решил изменить и

<div>
<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
<form enctype="multipart/form-data" method="post">
</div>
<div style="clear:both"></div>
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>
<div style="clear:both"></div>

Итак, вывод состоит в том, что после <form enctype="multipart/form-data" method="post"> должно быть <input name, type, id и не должно быть <div> или некоторых других тегов

В моей ситуации правильный код был

<div>
<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
</div>
<div style="clear:both"></div>
<form enctype="multipart/form-data" method="post">
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>
<div style="clear:both"></div>
0

У меня была аналогичная проблема, и проблема была неверной в htaccess, как упоминалось в shamittomar.

Измените php_value post_max_size 10MB на php_value post_max_size 10M

0

Если ваш основной script http://Some_long_URL/index.php, будьте осторожны, чтобы указать полный URL (с явным index.php и не только http://Some_long_URL) в поле action. Удивительно, но если нет, выполняется правильный script, но с пустым $_FILES!

0

У меня такая же проблема, и ни одна из тем не была моей ошибкой. Проверьте файл .htaccess, если он у вас есть, если включены "MultiViews". Я должен был отключить их.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню