Частые ошибки возникающие при загрузке файлов на сервер на PHP


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

Наш тестовый файл будет такой:

<?
if (!empty($_FILES['img']))
    {

    echo '<pre>';
    print_r($_FILES);
    echo '</pre>';
       
    if(move_uploaded_file($_FILES['img']['tmp_name'], $_SERVER['DOCUMENT_ROOT']."/".$_FILES['img']['name']))
                     {
                     echo '<p style="color:green">Файл удачно загружен!</p>';
                     }
                     else
                     {
        echo '<p style="color:red">Ошибка загрузки файла - '.$_FILES['img']['error'].'</p>';
        }

    }
    else
    {
    echo '<p>Выберите файл</p>';
    }
?>

<form action="" method="post" enctype="multipart/form-data">
  <input name="img" type="file">
  <input type="submit" value="Загрузить">
</form>

Теперь посмотрим что я тут написал:

Самая первая проверка – это проверка на наличие загружаемого файла. Если его нет, выводим сообщение на экран «Выберите файл». Если файл выбран, то начинаем нашу загрузку.

Для начала, в тегах <pre></pre> я показываю содержимое массива $_FILES. Все файлы выбранные в input типа file, отправляются в этот массив. Чтобы было понятнее с чем мы работаем, все его содержимое я вывожу на экран в отформатированном виде (print_r($_FILES)). Теперь когда мы выберем какой-нибудь файл, и попытаемся его загрузить, мы увидим что-то подобное:

Array
(
    [img] => Array
        (
            [name] => article.docx
            [type] => application/vnd.openxmlformats-officedocument.wordprocessingml.document
            [tmp_name] => Z:\tmp\php426E.tmp
            [error] => 0
            [size] => 12065
        )
)

Что означают элементы этого массива, мы рассмотрим позже. А сейчас посмотрим как проходит загрузка файла на PHP.

Перед попаданием файла в массив $_FILES, файл загружается во временную директорию на сервере (кстати, именно она и показывается в элементе tmp_name массива $_FILES). Затем при помощи функции move_uploaded_file() этот файл копируется из временной директории в указанную вторым параметром у функции (первый, как уже стало наверное понятно – это путь к файлу во временной директории). Стоит отметить что путь к директории нужно указывать относительно корня сервер. Для этого используем элемент глобального массива -  $_SERVER['DOCUMENT_ROOT']. На этом загрузка файла закончена. Я думаю тут ничего нет сложного.

Теперь рассмотрим что же находится в массиве $_FILES.

В данный массив попадают все файлы выбранные в форме, предварительно загрузившись во временную директорию. Ещё туда сразу заносится информация о файле:

  • name – Имя загружаемого файла. Чтобы избежать многих проблем, лучше загружать файлы на латинице.
  • type -  Тип файла. Этой переменной можно определять тип загружаемого файла, чтобы потом фильтровать их. Например, чтобы хакер не смог загрузить файл с расширением «.php», который даст ему доступ к всему серверу. Отмечу, что это не лучший вариант для проверки типа загружаемого файла, но он имеет право на существование.
  • tmp_name – Тут хранится путь к временному фалу, который мы в последствии и копируем в необходимую нам директорию.
  • error – Этот элемент массива хранит код ошибки. Если он равен 0 значит ошибок нет. В приведённом мной примере видно, что я показываю эту ошибку при проблеме во время загрузки файла. Подробнее о этих кодах поговорим чуть ниже.
  • size – Тут, как уже наверное понятно, размер загружаемого файла в байтах.

Теперь рассмотрим частые ошибки при загрузке файлов на сервер на PHP.

В элементе массива error может быть только 8 вариантов ошибок (половина добавлена в 5 версии):

  • 0 – Ошибок нет. Файл удачно загружен на сервер
  • 1 – У файла слишком большой размер. Этот размер настраивается в конфигурационном файле php.ini директивой upload_max_filesize. Так что если увидели там 1 – лезьте в php.ini (если у вас есть доступ к нему) либо связывайтесь с вашим хостером, и говорите ему чтоб увеличил upload_max_filesize.
  • 2 – Размер файла больше чем указано в параметре MAX_FILE_SIZE, указанном в форме (<form action="" method="post" enctype="multipart/form-data" MAX_FILE_SIZE="10000">). Если этот параметр не указан, то данное условие не проверяется.
  • 3 – Файл был загружен частично. Связано это скорее всего с перебоями в сети. Если случилась подобная ошибка, то стоит повторить попытку загрузки файла.
  • 4 – Файл не загружен. Причина неизвестна, но часто бывает такое, что вы просто забыли указать форме параметр enctype="multipart/form-data" или дать файлу права на запись.
  • 6 – Временная папка не найдена. Ошибка возникает крайне редко, но все же иногда бывает. Данная ошибка добавлена в PHP 4.3.10 и PHP 5.0.3.
  • 7 – Не удалось записать файл на диск. Ошибка может быть связанна с многими факторами, например переполнение диска, ограничение квоты, недостаточно прав для записи, физическое повреждение сектора жёсткого диска и т.д.
  • 8 – Какое-то из расширений PHP прервало загрузку фала.  Какое конкретно это сделало, узнать тяжело, но самый простой способ это просмотр списка установленных расширений в phpinfo(), затем поочерёдно отключение каждого из них.

Так же часто новички допускают следующие ошибки при загрузке файлов на PHP:

  • Не указан enctype="multipart/form-data" в форме загрузчика
  • Файлу загрузчику не даны права на запись файла. Для этого в любом FTP менеджере, например FileZilla выбрать файл загрузчик, нажать правой кнопкой мыши и выбрать пункт «Права доступа к файлу». Затем поставить галочки напротив всех пунктов «Запись».
  • Обращаются не по тому имени фала, указанного в атрибуте формы – name.

Настоятельно рекомендую на этапе отладки загрузки файла постоянно выводить содержимое массива $_FILES следующим кодом:

echo '<pre>';
print_r($_FILES);
echo '</pre>';

Именно так я сделал в своем примере чтобы постоянно контролировать содержимое этого массива.

 


Тэги:

Комментарии: 3

Прокомментировать »

 
 
Alex
5.07.2013
 

У меня вопрос , у меня ошибка номер 6 Как мне ее исправить ? Надо вручную папку что ли создавать ??

lavrik
5.07.2013
 

При ошибке номер 6, вам необходимо обратиться к своим хостерам. Вероятнее всего проблема с настройкой apache. Вряд ли у вас будут все права для редактирования конфигурационного файла php.ini.

Max
11.07.2013
 

Проблема с параметром upload_tmp_dir в файле php.ini. Если не сможешь нормально его настроить просто закоментируй этот параметр. Сервер сам выберет директорию по умолчанию. Комментируются параметры знаком точки с запятой ";" перед этим параметром.

 

Прокомментировать

 
 
Сообщение *
 
Проверочный код *
 
 
 
Яндекс.Метрика