Web

Почему $_FILES может быть пустым при загрузке файлов в 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">

        Выберите файл для загрузки: <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";

?>

 

Ответ 1

Вот контрольный список для загрузки файлов в 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 или из блога веб-сайта (WordPress преобразует прямые кавычки в угловые!). Если у вас есть несколько форм на странице, убедитесь, что у них обоих есть этот атрибут. Введите их вручную или попробуйте ввести прямые одинарные кавычки вручную.

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

<input type="file" name="files[]">

<input type="file" name="files[]">

 

  1. Убедитесь, что в ваших каталогах tmp и upload установлены правильные разрешения на чтение и запись. Папка для временной загрузки указывается в настройках PHP как upload_tmp_dir.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

 

Ответ 2

Важно добавить 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>

 

Ответ 3

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

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

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

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

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

 

Ответ 4

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

Вот еще одна вещь для проверки, о которой ранее не упоминалось… 

Естественно, я предполагал, что папка, в которой мой PHP-скрипт хранит временные загруженные файлы, это /tmp. Это предположение было подкреплено тем фактом, что echo sys_get_temp_dir() . PHP_EOL; возвращает/tmp. Также echo ini_get('upload_tmp_dir'); ничего не возвращает.

Чтобы проверить, что загруженный файл действительно ненадолго появляется в моей папке /tmp, я добавил оператор sleep(30); в свой скрипт и перешел в папку /tmp в cPanel File Manager, чтобы найти файл. Однако, несмотря ни на что, загруженный файл нигде не был найден.

Наконец, после поиска в файлах моего сайта по запросу tmp я обнаружил, что на сайте есть другие папки с именем tmp в разных каталогах. Я понял, что мой PHP-скрипт, на самом деле, записывал загруженные файлы в .cagefs/tmp (для просмотра этой папки в cPanel должна быть включена настройка «Показывать скрытые файлы»).

Итак, почему функция sys_get_temp_dir возвращает неточную информацию?

Вот объяснение с веб-страницы PHP.net для sys_get_temp_dir:

При работе в системе Linux, где в systemd установлено PrivateTmp=true (что является значением по умолчанию в CentOS 7 и, возможно, других более новых дистрибутивах), эта функция вернет просто "/tmp", а не абсолютный, правильно установленный путь к временной папке.

Схожие статьи

Web

Что это значит: ошибка 720 при подключении к VPN, можно ли исправить

Google DNS не работает: как исправить эту проблему самостоятельно?
Web

Google DNS не работает: как исправить эту проблему самостоятельно?

Web

Как получить первый элемент массива в PHP

Web

Как проверить xml-файл на ошибки, какой плагин для этого использовать

×