Календарь
Расписание
май 2024
 -  - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  -  -

Что учитывать при загрузке файлов на сервер

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

Например, создавать простенький блог, в котором автор может прикреплять к своим статьям изображения. А может быть, огромную социальную сеть, где пользователи будут добавлять аватарки к своим профилям. Или же простейшую галерею фотографий. Объединяет все эти примеры одно – в них будет происходить загрузка пользовательского файла на сервер.

Для того чтобы напомнить Вам, как файл загружается на сервер, рассмотрим простенький скрипт. Нам потребуется html –формочка и её php-обработчик.

Итак, форма:

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

В ней нет никаких примечательных моментов за исключением указания enctype = «multipart/form-data», которое необходимо, если с формы мы осуществляем загрузку файла.

Теперь напишем самый простой php-обработчик:

<?php
if (isset($_FILES['file'])) // если была произведена отправка формы
{
  // копируем файл из временной директории
  copy($_FILES['file']['tmp_name'], $_FILES['file']['name']);
  echo 'Файл успешно загружен';
}

Объединим это всё в один файл:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Загрузка файла на сервер</title>
  </head>
  <body>
    <form method="post" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit" value="Загрузить файл!">
    </form>
    <?php
    if (isset($_FILES['file'])) // если была произведена отправка формы
    {
      // копируем файл из временной директории
      copy($_FILES['file']['tmp_name'], $_FILES['file']['name']);
      echo 'Файл успешно загружен';
    }
    ?>
  </body>
</html>

А теперь давайте попробуем поискать недостатки у данного скрипта.

Во-первых, пользователь может просто не выбрать файл на форме. В итоге функция copy() попытается скопировать из временной директории файл, которого нет, что приведёт к ошибке.

Во-вторых, пользователь может выбрать фотографию, которая весит, допустим, мегабайт 20 (а если он злоумышленник или шутник – видеофайл весом в 20 Гб). Стоит задуматься, нужны ли нам файлы такого размера у себя на сайте!?

Обработаем в скрипте обе эти ситуации (изменения показываются в обработчике):

<?php
// если была произведена отправка формы
if (isset($_FILES['file']))  
{ 
  //если имя файла пустое 
  if($_FILES['file']['name'] == '') 
    echo ('Файл не выбран!');
    //если размер файла превышает 1 Мб
  elseif($_FILES['file']['size'] > 1048576) 
    echo ('Размер файла превышает 1 Мб!');
  else{
    // копируем файл из временной директории
    copy($_FILES['file']['tmp_name'], $_FILES['file']['name']);
    echo 'Файл успешно загружен';
  }
}

Ну что ж, кажется, всё! Осталось лишь где-нибудь добавить проверку на расширение загружаемого файла, и всё будет готово?

Нет! Сейчас нам необходимо вспомнить, из каких частей состоит закачка файла на сервер:

  1. файл с компьютера пользователя автоматически загружается на сервер в директорию, где хранятся все временные файлы. На денвере, например, это папка tmp;
  2. мы выполняем все проверки и перемещаем файл из временного хранилища в реальное с помощью функции copy().

Т.е. смотрите, что происходит: файл сразу же оказывается на сервере ещё до того, как исполнится первая строчка нашего php-кода. Где же тогда ставить защиту от загрузки злоумышленниками и шутниками файлов огромных размеров?

Может быть, с помощью скрытого поля на html-форме? Например:

<form method="post" enctype="multipart/form-data">
   <input name="MAX_FILE_SIZE" value="1048576">
   <input type="file" name="file">
   <input type="submit" value="Загрузить файл!">
</form>

Как бы бредово не выглядела данная запись, но она реально работает. С помощью дополнительного скрытого поля ввода:

<input name="MAX_FILE_SIZE" value="1048576">

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

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

Находится он по адресу /usr/local/php5/php.ini. Советую Вам сейчас его открыть (если Вы конечно используете денвер).

Итак, здесь нас интересует 552-ая строчка:

upload_max_filesize = 2M

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

Всё, теперь мы можем грамотно управлять размером загружаемых на сервер файлов. Осталось только разобраться с их количеством. Согласитесь, что если пользователь подделает отправку формы и наплодит на ней 1000 полей ввода, в которые поместит по двухмегабайтному файлу, результат для нас также будет очень печальным.

Установить максимальное количество загружаемых на сервер файлов мы можем с помощью специальной функции ini_set(). В самое начало нашего скрипта допишем:

ini_set(‘max_file_uploads’, ’5′);

Ура! Теперь за один раз никто не сможет загрузить к нам на сервер более 5 файлов.

Подводя итоги, хочу ещё раз перечислить все пункты, про которые Вы должны помнить, если организуете загрузку файлов на сервер:

  1. у html формы обязательно указывайте enctype = «multipart/form-data»
  2. делайте проверку, не является ли имя файла пустым (т.е. выбрал ли вообще пользователь файл)
  3. делайте проверку на размер и тип загружаемого файла в скрипте
  4. устанавливайте максимальный размер загружаемого файла в конфигурационном файле на сервере
  5. с помощью функции ini_set() устанавливайте максимальное количество загружаемых файлов

21.03.2015

Понравился материал? Поделись с друзьями!