Почему $ФАЙЛЫ должны быть пустыми при загрузке файлов в PHP?
На моем компьютере с Windows 7 установлен сервер WampServer 2. Я использую 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";
?>
20 answers
Вот контрольный список для загрузки файлов на PHP:
-
Проверьте php.ini на наличие:
file_uploads = On
post_max_size = 100M
upload_max_filesize = 100M
- Возможно, вам потребуется использовать
.htaccess
или.user.ini
, если вы находитесь на общем хостинге и не имеете доступа кphp.ini
. - Убедитесь
, что вы редактируете правильный ini–файл -
используйте функцию
phpinfo()
, чтобы убедиться, что ваши настройки действительно применяются. - Также убедитесь, что вы не
ошиблись в размерах - это должно быть
100M
не100MB
.
- Возможно, вам потребуется использовать
Убедитесь, что ваш тег
<form>
имеет атрибутenctype="multipart/form-data"
. Никакой другой тег не будет работать, это должен быть ваш тег ФОРМЫ. Дважды проверьте, правильно ли написано . Дважды проверьте, что составные данные/данные формы окружены ПРЯМЫМИ КАВЫЧКАМИ, а не умными кавычками, вставленными из Word ИЛИ из блога веб-сайта (WordPress преобразует прямые кавычки в угловые кавычки!). Если у вас на странице несколько форм, убедитесь, что у них обоих есть этот атрибут. Введите их вручную или попробуйте прямые одинарные кавычки, введенные вручную.-
Убедитесь, что у вас нет двух полей входного файла с одним и тем же атрибутом
name
. Если вам нужно поддерживать несколько, поставьте квадратные скобки в конце имени:<input type="file" name="files[]"> <input type="file" name="files[]">
Убедитесь, что в ваших каталогах tmp и upload установлены правильные разрешения на чтение и запись. Временная папка загрузки указана в настройках PHP как
upload_tmp_dir
.Убедитесь, что ваше место назначения файла и каталоги tmp/upload соответствуют в них нет пробелов.
Убедитесь, что все
<form>
на вашей странице имеют</form>
закрывающие теги.Убедитесь, что в теге вашей ФОРМЫ есть
method="POST"
. Запросы GET не поддерживают загрузку данных из нескольких частей/форм.Убедитесь, что у вашего тега ввода файла есть атрибут NAME. Атрибута ID НЕДОСТАТОЧНО! Атрибуты идентификатора предназначены для использования в DOM, а не для почтовых полезных нагрузок.
Убедитесь, что вы не используете Javascript для отключения поля
<input type="file">
на подчинениеУбедитесь, что вы не вкладываете такие формы, как
<form><form></form></form>
Проверьте свою структуру HTML на наличие недопустимых/перекрывающихся тегов, таких как
<div><form></div></form>
Также убедитесь, что в загружаемом файле нет никаких не буквенно-цифровых символов.
Однажды я просто потратил несколько часов, пытаясь понять, почему это вдруг произошло со мной. Оказалось, что я изменил некоторые настройки PHP в
.htaccess
, и один из них (пока не уверен, что именно) приводило к сбою загрузки и$_FILES
было пустым.Потенциально вы можете попытаться избежать подчеркивания (
_
) в атрибутеname=""
тега<input>
Попробуйте загрузить очень маленькие файлы, чтобы определить, является ли это проблемой размера файла.
-
Проверьте доступное место на диске. Хотя это очень редко, это упоминается в этом комментарии к странице руководства по PHP :
Если массив $_FILES внезапно исчезнет таинственно пустой, даже если ваша форма кажется правильной, вам следует проверить место на диске, доступное для раздела временной папки. В моей установке все загрузки файлов завершились без предупреждения. После долгого скрежета зубов я попытался освободить дополнительное пространство, после чего загрузка файлов внезапно снова заработала.
Источник для некоторых из них points:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/
Что касается 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
?
Важно добавить 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>
Спасибо всем за исчерпывающие ответы. Все это очень полезно. Ответ оказался чем-то очень странным. Оказывается, PHP 5.2.11 не нравится следующее:
post_max_size = 2G
Или
post_max_size = 2048M
Если я изменю его на 2047M
, загрузка будет работать.
Убедитесь, что ваш form
имеет следующий атрибут enctype="multipart/form-data"
.
Вот еще одна причина, которую я нашел: При использовании jQuery Mobile и атрибуте формы data-ajax установлено значение true, массив ФАЙЛОВ будет пустым. Поэтому установите для data-ajax значение false.
Убедитесь, что у вашего входного элемента есть атрибут "имя".
<input type="file" name="uploadedfile" />
Если это отсутствует, то $_FILES будут пустыми.
У меня такая же проблема, смотрю 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
Я боролся с той же проблемой и тестировал все, не получая отчетов об ошибках, и, казалось, все было в порядке. У меня была ошибка_отчета (E_ALL) Но вдруг я понял, что не проверил журнал apache, и вуаля! В сценарии была синтаксическая ошибка...! (отсутствует "}")
Таким образом, даже если это что-то очевидное, что нужно проверить, об этом можно забыть... В моем случае (linux) он находится по адресу:
/var/log/apache2/error.log
Если вы пытаетесь загрузить массив файлов, вам может потребоваться увеличить max_file_uploads
в php.ini
, который по умолчанию установлен в 20
Примечание: max_file_uploads
не может быть изменен за пределами php.ini. Смотрите PHP "Ошибка" #50684
Еще один возможный виновник - перенаправление apache. В моем случае у меня был настроен httpd.conf apache для перенаправления определенных страниц на нашем сайте на http-версии, а других страниц на https-версии страницы, если они еще не были. Страница, на которой у меня была форма с вводом файла, была одной из страниц, настроенных для принудительного использования ssl, но страница, обозначенная как действие формы, была настроена на http. Таким образом, страница отправляла загрузку на ssl-версию страницы действий, но apache был перенаправление его на http-версию страницы и данные публикации, включая загруженный файл, были потеряны.
Никто не упоминал об этом, но это помогло мне, и не так много мест в сети упоминают об этом.
Убедитесь, что в вашем php.ini установлен следующий ключ:
upload_tmp_dir="/path/to/some/tmp/folder"
Вам нужно будет уточнить у своего веб-хостинга, хотят ли они, чтобы вы использовали абсолютный путь к файлу сервера. Вы должны иметь возможность увидеть другие примеры каталогов в вашем файле php.ini, чтобы определить это. Как только я установил его, я получил значения в своем объекте _FILES.
Наконец, убедитесь, что ваша папка tmp и куда бы вы ни перемещали файлы иметь правильные разрешения, чтобы их можно было читать и записывать.
Я столкнулся с той же проблемой и обнаружил, что моя IDE была частью проблемы. Я запускал отладчик непосредственно из IDE (PhpStorm) вместо того, чтобы просто напрямую использовать браузер. URL-адрес, созданный IDE, был таким:
"...localhost:63342/CB_Upload/index.php?_ijt=j2hcbacqepj87bvg66ncuohvne"
И просто используя:
"...localhost/CB_Upload/index.php"
Сработало просто отлично. Моя настройка - PC/Windows 10/WAMPSERVER 3.0.6 64-битный
Проверьте свой php.ini на наличие enable_post_data_reading=На , потому что:
Отключение этой опции приводит к тому, что $_POST и $_FILES не заполняются . Единственный способ прочитать postdata будет тогда через php://оболочку входного потока. (...)
В http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading
У меня была та же проблема, и ни одна из тем не была моей ошибкой. Проверьте свой файл.htaccess, если он у вас есть, если "мультивидения" включены. Мне пришлось отключить их.
Если ваш основной скрипт http://Some_long_URL/index.php
, будьте осторожны, чтобы указать полный URL-адрес (с явными index.php
и , а не только http://Some_long_URL
) в поле action
. Удивительно, но если нет, то выполняется правильный скрипт, но с пустыми $_FILES!
У меня была аналогичная проблема, и проблема была в неправильном значении в htaccess, как упоминал шамиттомар.
Измените php_value post_max_size 10MB
на php_value post_max_size 10M
Я был пуст $_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>
У меня тоже были проблемы с пустыми файлами $_. В приведенном выше контрольном списке не упоминаются мультивидения в.htaccess, httpd.conf или httpd-vhost.conf.
Если у вас есть несколько просмотров, установленных в директиве options для вашего каталога, содержащего веб-сайт, $_FILES будет пустым, даже если заголовок длиной с содержимое, если он показывает, что файл, который я загрузил.
Если вы используете jQuery Mobile
Использование составной формы с файловым вводом не поддерживается Ajax. В этом случае вы должны украсить родительскую форму данными-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>