Php не загружается файл на сервер
На моем компьютере с Windows 7 установлен WampServer 2. Я использую Apache 2.2.11 и PHP 5.2.11. Когда я пытаюсь загрузить какой-либо файл из формы, кажется, что он загружается, но в PHP $_FILES массив пуст. В c:\wamp\tmp папке нет файла. Я настроил в php.ini разрешение на загрузку файлов и тому подобное. Папка tmp имеет привилегии чтения/записи для текущего пользователя. Я в тупике.
HTML:
Выберите файл для загрузки:
PHP:
echo 'file count=', count($_FILES),"\n";
var_dump($_FILES);
echo "\n";
?>
Загрузка одного файла
Чтобы форма отправила файл, необходимо использовать только метод POST для отправки данных и добавить к тегу атрибут enctype="multipart/form-data" , который определяет способ кодирования данных формы при их отправке на сервер.
Код скрипта index.php:
Результат:
Описание значений массива $_FILES :
$_FILES['file-1']['name'] | Оригинальное имя файла на компьютере клиента. |
$_FILES['file-1']['type'] | Mime-тип файла, в случае, если браузер предоставил такую информацию. Этот mime-тип не проверяется на стороне PHP, так что не полагайтесь на его значение без проверки. |
$_FILES['file-1']['size'] | Размер принятого файла в байтах . |
$_FILES['file-1']['tmp_name'] | Временное имя, с которым принятый файл был сохранен на сервере. |
$_FILES['file-1']['error'] | Код ошибки, которая может возникнуть при загрузке файла. |
Решение
В Вашем случае загружаемый файл превышает максимальный размер, указанный в параметре upload_max_filesize файла php.ini.
И на будущее, прежде чем переносить файлы, проверяйте переменную $_FILES['userfile']['error'] на наличие ошибок.
Добавлено через 3 минуты
В .htaccess у меня прописано
Но он всё равно выводит значение=2
Добавлено через 43 секунды
В Вашем случае загружаемый файл превышает максимальный размер, указанный в параметре upload_max_filesize файла php.ini.
И на будущее, прежде чем переносить файлы, проверяйте переменную $_FILES['userfile']['error'] на наличие ошибок.
Добавлено через 3 минуты
Кстати от этого тоже не помешало бы избавиться.
А почему Вы не хотите сделать это в php.ini? При определенных условиях эти строки в .htaccess не будут иметь никакого эффекта.
А почему Вы не хотите сделать это в php.ini? При определенных условиях эти строки в .htaccess не будут иметь никакого эффекта.
Ответ 1
Проверьте php.ini на наличие:
file_uploads = On
post_max_size = 100M
upload_max_filesize = 100MВозможно, вам придется использовать .htaccess или .user.ini, если вы находитесь на виртуальном хостинге и не имеете доступа к php.ini .
Убедитесь, что вы редактируете правильный ini-файл — используйте функцию phpinfo() , чтобы убедиться, что ваши настройки действительно применяются.
Кроме того, убедитесь, что вы не сделали орфографических ошибок. Размеры должны быть 100M, а не 100MB .
Убедитесь, что у вашего
Убедитесь, что у вас нет двух полей входного файла с одинаковым атрибутом « name ». Если вам нужно поддерживать несколько, поставьте в конце имени квадратные скобки:
Убедитесь, что в ваших каталогах tmp и upload установлены правильные разрешения на чтение и запись. Папка для временной загрузки указывается в настройках PHP как upload_tmp_dir .
Убедитесь, что в папке назначения файла и в каталогах tmp/upload нет пробелов.
Убедитесь, что у всех
.Убедитесь, что в вашем теге FORM есть method="POST" . Запросы GET не поддерживают загрузку данных из нескольких частей данных.
Убедитесь, что в теге ввода файла есть атрибут NAME. Атрибут ID НЕ достаточен! Атрибуты ID предназначены для использования в DOM, а не для полезных данных POST.
Убедитесь, что вы не используете Javascript, чтобы отключить поле при отправке.
Убедитесь, что вы не используете такие формы вложенности, как .
Проверьте свою HTML-структуру на наличие недопустимых/перекрывающихся тегов, например .
Также убедитесь, что в загружаемом файле нет символов, отличных от буквенно-цифровых.
Однажды я потратил несколько часов, пытаясь понять, почему это произошло со мной. Оказалось, что я изменил некоторые настройки PHP .htaccess , и один из них (еще не уверен, какой именно) приводил к тому, что загрузка не выполнялась и $_FILES оставался пустым.
Вы можете попробовать избегать подчеркивания ( _ ) в name="" атрибуте тега.
Попробуйте загружать очень маленькие файлы, чтобы сузить круг вопросов, связанных с размером файла.
Проверьте доступное дисковое пространство. Хотя это и очень редко, но упоминается в этом комментарии к странице руководства PHP:
Убедитесь, что вы не отправляете форму через запрос AJAX POST вместо обычного запроса POST, который вызывает перезагрузку страницы. Я просмотрел каждый пункт в приведенном выше списке и, наконец, обнаружил, что причина, по которой моя переменная $ _FILES была пустой, заключалась в том, что я отправлял форму с помощью запроса AJAX POST. Я знаю, что есть методы для загрузки файлов с помощью ajax, но это может быть веской причиной, по которой ваш массив $_FILES останется пустым.
Ответ 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", а не абсолютный, правильно установленный путь к временной папке.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Опция MAX_FILE_SIZE не должна позволять передачу файлов, размер которых превышает лимит, установленный конфигурационной директивой upload_max_filesize в php.ini . Ограничение по умолчанию составляет 2 мегабайта.
В случае, если установлены ограничения памяти, вам может понадобиться увеличить значение опции memory_limit. Убедитесь в том, что значение memory_limit достаточно велико.
В случае, если опция max_execution_time установлена слишком маленьким значением, необходимое время работы скрипта может превышать это значение. Убедитесь в том, что значение max_execution_time достаточно велико.
Замечание: Директива max_execution_time касается исключительно времени, используемого непосредственно самим скриптом. Время, потраченное на внешние действия, такие как системные вызовы при помощи функции system() или sleep() , обращения к базе данных, а также время, потраченное на загрузку файла и другие действия, происходящие вне скрипта, не учитываются при определении максимально допустимого промежутка времени, отведённого для выполнения скрипта.
Директива max_input_time указывает максимально допустимое время в секундах для получения входящих данных, в том числе и загружаемых файлов. В случае, если вы имеете дело с несколькими или большими файлами, либо удалённые пользователи используют медленный канал, ограничение по умолчанию в 60 секунд может быть превышено.
Если директива post_max_size слишком мала, большие файлы не смогут быть загружены на сервер. Убедитесь, что значение директивы post_max_size достаточно велико.
Опция max_file_uploads контролирует максимальное количество загружаемых файлов в течение одного запроса. Если загружается большее количество файлов, чем указано в этом ограничении, то массив $_FILES прекратит дальнейшую обработку файлов по достижении этого ограничения. Например, если max_file_uploads установлено в 10 , то $_FILES никогда не будет содержать больше 10 элементов.
Если не проверять, с какими файлами вы работаете, пользователи могут получить доступ к конфиденциальной информации, расположенной в других директориях.
Поскольку разные системы по-разному работают с файловой структурой, нет никаких гарантий того, что файлы с экзотическими именами (например, которые содержат пробельные символы) будут обработаны корректно.
Разработчики не должны использовать одинаковые имена для обычных полей ввода (тег input ) и полей выбора файла в пределах одной и той же формы (например, используя имя для тега input наподобие foo[] ).
$_FILES and $_POST will return empty
We use this function to handle file uploads.
Since $_FILES allows for more than a single file, this loops through each file and if there's an error, it is displayed in human readable language to the error log and then returned / exited. You can adjust that to echo's if preferred:
error_log("======================================= $messageBefore");
error_log("======================================= cmmediabrowsedfor"]["tmp_name"][0]) || !is_uploaded_file($_FILES["cmmediabrowsedfor"]["tmp_name"][0])) error_log("NO FILE GOT UPLOADED ");
> else error_log("SUCCESS FILE GOT UPLOADED ");
>
>
Clarification on the MAX_FILE_SIZE hidden form field and the UPLOAD_ERR_FORM_SIZE error code:
PHP has the somewhat strange feature of checking multiple "maximum file sizes".
The two widely known limits are the php.ini settings "post_max_size" and "upload_max_size", which in combination impose a hard limit on the maximum amount of data that can be received.
In addition to this PHP somehow got implemented a soft limit feature. It checks the existance of a form field names "max_file_size" (upper case is also OK), which should contain an integer with the maximum number of bytes allowed. If the uploaded file is bigger than the integer in this field, PHP disallows this upload and presents an error code in the $_FILES-Array.
One thing that is annoying is that the way these constant values are handled requires processing no error with the equality, which wastes a little bit of space. Even though "no error" is 0, which typically evaluates to "false" in an if statement, it will always evaluate to true in this context.
So, instead of this:
-----
if( $_FILES [ 'userfile' ][ 'error' ]) <
// handle the error
> else <
// process
>
?>
-----
You have to do this:
-----
if( $_FILES [ 'userfile' ][ 'error' ]== 0 ) <
// process
> else <
// handle the error
>
?>
-----
Also, ctype_digit fails, but is_int works. If you're wondering. no, it doesn't make any sense.
You ask the question: Why make stuff complicated when you can make it easy? I ask the same question since the version of the code you / Anonymous / Thalent (per danbrown) have posted is unnecessary overhead and would result in a function call, as well as a potentially lengthy switch statement. In a loop, that would be deadly. try this instead:
-----
$error_types = array(
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.' ,
'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.' ,
'The uploaded file was only partially uploaded.' ,
'No file was uploaded.' ,
6 => 'Missing a temporary folder.' ,
'Failed to write file to disk.' ,
'A PHP extension stopped the file upload.'
);
// Outside a loop.
if( $_FILES [ 'userfile' ][ 'error' ]== 0 ) <
// process
> else <
$error_message = $error_types [ $_FILES [ 'userfile' ][ 'error' ]];
// do whatever with the error message
>
// In a loop.
for( $x = 0 , $y = count ( $_FILES [ 'userfile' ][ 'error' ]); $x < $y ;++ $x ) <
if( $_FILES [ 'userfile' ][ 'error' ][ $x ]== 0 ) <
// process
> else <
$error_message = $error_types [ $_FILES [ 'userfile' ][ 'error' ][ $x ]];
// Do whatever with the error message
>
>
// When you're done. if you aren't doing all of this in a function that's about to end / complete all the processing and want to reclaim the memory
unset( $error_types );
?>
When uploading a file, it is common to visit the php.ini and set up upload_tmp_dir = /temp but in the case of some web hostess as fatcow you need to direct not only /tmp but upload_tmp_dir = /hermes/walnaweb13a/b345/moo.youruser/tmp
I have expanded @adam at gotlinux dot us's example a bit with proper UPLOAD_FOO constants and gettext support. Also UPLOAD_ERR_EXTENSION is added (was missing in his version). Hope this helps someone.
class Some /**
* Upload error codes
* @var array
*/
private static $upload_errors = [];
public function __construct () // Init upload errors
self :: $upload_errors = [
UPLOAD_ERR_OK => _ ( 'There is no error, the file uploaded with success.' ),
UPLOAD_ERR_INI_SIZE => _ ( 'The uploaded file exceeds the upload_max_filesize directive in php.ini.' ),
UPLOAD_ERR_FORM_SIZE => _ ( 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.' ),
UPLOAD_ERR_PARTIAL => _ ( 'The uploaded file was only partially uploaded.' ),
UPLOAD_ERR_NO_FILE => _ ( 'No file was uploaded.' ),
UPLOAD_ERR_NO_TMP_DIR => _ ( 'Missing a temporary folder.' ),
UPLOAD_ERR_CANT_WRITE => _ ( 'Cannot write to target directory. Please fix CHMOD.' ),
UPLOAD_ERR_EXTENSION => _ ( 'A PHP extension stopped the file upload.' ),
];
>
>
?>
In regards to the dud filename being sent, a very simple way to check for this is to check the file size as well as the file name. For example, to check the file size simple use the size attribute in your file info array:
if( $_FILES [ "file_id" ][ "size" ] == 0 )
<
// . PROCESS ERROR
>
?>
I noticed that on PHP-4.3.2 that $_FILES can also not be set if the file uploaded exceeds the limits set by upload-max-filesize in the php.ini, rather than setting error $_FILES["file"]["error"]
UPLOAD_ERR_PARTIAL is given when the mime boundary is not found after the file data. A possibly cause for this is that the upload was cancelled by the user (pressed ESC, etc).
Note: something that might surprise you, PHP also provides a value in the $_FILES array, if the input element has no value at all, stating an error UPLOAD_ERR_NO_FILE.
So UPLOAD_ERR_NO_FILE is not an error, but a note that the input element just had no value. Thus you can't rely on the $_FILES array to see if a file was provided. Instead you have to walk the array and check every single damn entry - which can be quite difficult since the values may be nested if you use input elements named like "foo[bar][bla]".
Seems like PHP just introduced you to yet another common pitfall.
I've been playing around with the file size limits and with respect to the post_max_size setting, there appears to be a hard limit of 2047M. Any number that you specify above that results in a failed upload without any informative error describing what went wrong. This happens regardless of how small the file you're uploading may be. On error, my page attempts to output the name of the original file. But what I discovered is that this original file name, which I maintained in a local variable, actually gets corrupted. Even my attempt to output the error code in $_FILES['uploadedfiles']['error'] returns an empty string/value.
Hopefully, this tidbit will save someone else some grief.
This updates "adam at gotlinux dot us" above and makes it version aware, and also adds newer constants to the array.
The reason we want to check the version is that the constants are not defined in earlier versions, and they appear later in the array. They would effectively overwrite the "0" index (no error) with an error message when the file actually uploaded fine.
It also drops the constant's value (0,1,2, etc) for the errors, in the likely event that they are changed later (the code should still work fine).
$upload_errors = array(
0 => "There is no error, the file uploaded with success"
, UPLOAD_ERR_INI_SIZE => "The uploaded file exceeds the upload_max_filesize directive in php.ini"
, UPLOAD_ERR_FORM_SIZE => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
, UPLOAD_ERR_PARTIAL => "The uploaded file was only partially uploaded"
, UPLOAD_ERR_NO_FILE => "No file was uploaded"
);
if ( version_compare ( PHP_VERSION , '5.0.3' ) >= 0 )
$upload_errors [ UPLOAD_ERR_NO_TMP_DIR ] = "Missing a temporary folder" ;
if ( version_compare ( PHP_VERSION , '5.1.0' ) >= 0 )
$upload_errors [ UPLOAD_ERR_CANT_WRITE ] = "Failed to write to disk" ;
if ( version_compare ( PHP_VERSION , '5.2.0' ) >= 0 )
$upload_errors [ UPLOAD_ERR_EXTENSION ] = "File upload stopped by extension" ;
?>
[Well just a little note. ]
That UploadException class example posted on top by anonymous is great. It works good. But there is a certain problem. You know there are two sides to generating errors.
First -> for the client side.
Second -> for the developers who will use your script
But i see only one side to generating Exceptions. ie For the developers.
Why ? Because when you generate an Exception, your script will come to an halt and do whatever you have defined in catch clause.
Now you dont want any client to see the Exception, do you ? I will not. The client will want to know what error occured in simple words they can understand instead of wanting their web app crashed if upload fails. So, dont generate exceptions. These errors should be collected and shown to client in an elegant way. That's a little advice.
Keep developing smarter.
Just found out that it is very important to define the
input type="hidden" name="MAX_FILE_SIZE" value=.
AFTER defining the input type="FILE" name=.
in your html/php.
If you swap them around, you will keep getting the filesize exceeded (error 2)!
Hope this helps.
Roger
enctype="multipart/form-data" works fine
Upload doesnt work, and no error?
actually, both $_FILES and $_REQUEST in the posted to script are empty?
just see, if "post_max_size" is lower than the data you want to load.
in the apache error log, there will be an entry like "Invalid method in request". and in the access log, there will be two requests: one for the POST, and another that starts with all "----" and produces a 501.
For those reading this manual in german (and/or probably some other languages) and you miss error numbers listed here, have a look to the english version of this page ;)
1. And what about multiple file upload ? - If there is an UPLOAD_ERR_INI_SIZE error with multiple files - we can`t detect it normaly ? . because that we have an array, but this error returns null and can`t use foreach. So, by having a multiple upload, we can`t normaly inform user about that.. we can just detect, that sizeof($_FILES["file"]["error"]) == 0 , but we can`t actualy return an error code. The max_file_size also is not an exit, becouse it refers on each file seperatly, but upload_max_filesize directive in php.ini refers to all files together. So, for example, if upload_max_filesize=8Mb , max_file_size = 7Mb and one of my files is 6.5Mb and other is 5Mb, it exeeds the upload_max_filesize - cant return an error, becouse we don`t know where to get that error.
Unfortunately we cannot get the file sizes on client side, even AJAX normaly can`t do that.
2. If in file field we paste something, like, D:\whatever , then there also isn`t an error to return in spite of that no such file at all.
Не загружает файлы на FTP-сервер
Здравствуйте, пытаюсь сделать загрузку файлов на FTP-сервер. Ранее этого не делал. Есть у меня.
Не загружаются файлы на локальный сервер
Здравствуйте, коллеги. При тестировании асинхронной загрузки формы с файловыми полями на сервер.
Не загружаются файлы на локальный сервер
Работаю на WIN 10. Локальный сервер Denwer. При при загрузке файла и попытке его перенести или.
Файлы php, мне надо открыть их, а компьютер загружает
У меня есть файлы php, которые нужно открыть. А компютер загружает файлы, не открывает.
Ну а какой результат работы скрипта то? У Вас же там полно echo натыкано и print_r, какие из них выводятся и что выводят?
Он ничего не выводит, а возвращает в default (Скрипт построен по принципу switch-case)
папка files находится в корне, отдельно от скрипта
Нужно было ?act=add
Вот только сам файл не заливается, пишет "Возможная атака с помощью файловой загрузки!"
Ответ 3
Никто не упомянул об этом, но это помогло мне, и не многие места в сети упоминают об этом.
Убедитесь, что ваш php.ini устанавливает следующий ключ:
upload_tmp_dir="/path/to/some/tmp/folder"
Вам нужно уточнить у вашего хостера, хотят ли они, чтобы вы использовали абсолютный путь к файлам сервера. Вы должны быть в состоянии увидеть другие примеры директорий в вашем файле php.ini, чтобы определить это. Как только я установил это значение, я получил значения в моем объекте $_FILES.
Наконец, убедитесь, что ваша папка tmp и папка, куда вы перемещаете файлы, имеют правильные разрешения, чтобы в них можно было читать и записывать.
Максимальный размер загружаемого файла
Размер загружаемого файла можно ограничить, добавив в форму скрытое поле с максимальным размером файла :
В случае превышения размера файла в переменной $_FILES['file-1']['error'] будет ошибка с кодом « 2 ».
Решение
Необходимо настроить локальный сервер для работы с PHP
Здравствуйте. Установлен Денвер. Имеется следующий код: <html> <head> <title>Tecтирование.
Локальный сервер Denwer-ошибка запуска php файла
Помогите решить проблему с запуском php файла на лок сервере. У меня есть два файла index.html (мой.
Удалить с FTP-сервера все файлы, которые были скачаны на локальный сервер
Здравствуйте, облазил весь Интернет не нашел подходящего решения. Суть задачи. Есть ftp, с.
Установить локальный сервер или все по отдельности? (php, apache, mysql)
Извиняюсь если не в тот раздел написал просто не знал в какой лучше )) Подскажите пожалуйста.
Как отправлять JSON файлы на сервер методом POST
Приложение должно принимать и отправлять дсон файлы на PHP сервер. С приёмом вреде всё хорошо, но.
В PHP-скрипте обработка загруженных через форму происходит через глобальный массив $_FILES , рассмотрим его содержимое:
Загрузка несколько файлов
Для загрузки сразу нескольких файлов к нужно добавить атрибут multiple , а к имени поля – [] .
Код скрипта index.php
Результат:
Как видно, структура массива разделена по свойствам, а не по файлам. Для удобства работы с циклом foreach массив $_FILES можно преобразовать:
Результат:
Ответ 2
Коды ошибок загрузки файлов
В случаи, если при загрузке файла произошла ошибка, в переменной $_FILES['file']['error'] будет содержатся её код. Возможны следующие значения:
Код | Константа | Описание |
---|---|---|
0 | UPLOAD_ERR_OK | Ошибок не возникло, файл успешно загружен на сервер. |
1 | UPLOAD_ERR_INI_SIZE | Размер файла превысил максимально допустимый размер, который задан директивой upload_max_filesize |
2 | UPLOAD_ERR_FORM_SIZE | Размер загружаемого файла превысил значение MAX_FILE_SIZE, указанное в HTML-форме. |
3 | UPLOAD_ERR_PARTIAL | Загружаемый файл был получен только частично. |
4 | UPLOAD_ERR_NO_FILE | Файл не был загружен. |
6 | UPLOAD_ERR_NO_TMP_DIR | Отсутствует временная папка. |
7 | UPLOAD_ERR_CANT_WRITE | Не удалось записать файл на диск (возникает, когда на хостинге закончилось место). |
8 | UPLOAD_ERR_EXTENSION | PHP-расширение остановило загрузку файла. |
Настройки PHP
Обычно настройки загрузки файлов на хостинге вполне нормальные и не вызывают проблем, но есть исключения. Если не загружаются большие файлы, то скорее всего установлен лимит на размер загружаемого файла, ограничено время загрузки файла или ограничено количество одновременных загрузок.
Посмотреть установленные значения можно с помощью функции phpinfo() , в разделе «Core».
Читайте также: