базовый курс

ГРУППА КУРСА

Загрузка файла на сайт

Иногда нужно дать пользователю возможность загрузить на сайт какой-то файл, например, фото или аватарку. Для этого используется форма, которая может выглядеть так:

HTML код:

8
9
10
11
12
<form action="takefile.php" enctype="multipart/form-data" method="post">
  <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
  <input type="file" name="myfile">
  <input type="submit" value="Отправить">
</form>

Файл отправляется методом POST. Тэгу <form> указан атрибут enctype, который устанавливает тип кодирования данных. При отправке файла его всегда нужно указывать.

У формы есть скрытый элемент, который позволяет установить максимальный размер файла. Он используется для того, чтобы пользователь не пытался отправить файл, имеющий размер больше, чем допускается на сервере. Нужно иметь в виду, что этот элемент применяется только для удобства пользователей. Ведь ограничения на стороне клиента можно обойти. Если Вам нужно ограничить максимальный размер файла, то это нужно делать на сервере.

Когда файл отправлен на сервер, в суперглобальном массиве $_FILES содержится информация о нём. Этот массив двухмерный, потому что файлов может быть несколько. Первое измерение имеет имя, которое установлено в атрибуте name тэга <input>, который отправляет файл. В примере установлено имя: myfile, значит элементы массива будут иметь такое имя.

Форма запускает файл takefile.php. Создадим этот файл и выведем массив $_FILES на экран:

takefile.php:

+
1
2
<?php
header('Content-type: text/html; charset=utf-8');
3
print_r($_FILES);

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

name - имя, которое имеет файл на стороне клиента

type - Mime-тип файла

tmp-name - временный адрес файла на сервере

error - код ошибки

size - размер файла

Самая важная информация - tpm-name. Это адрес файла сразу после загрузки на сервер.

При загрузке может возникнуть ошибка. Поэтому массив $_FILES содержит код ошибки. Существуют такие коды:

0 - ошибки нет

1 - файл превышает максимальный размер, установленный в директиве php.ini

2 - файл превышает максимальный размер, установленный в форме

3 - неполная загрузка

4 - файл не загружен

6 - нет временной папки

7 - файл не записался на диск

8 - загрузка остановлена PHP-расширением

Для перемещения файла в нужную папку существует функция move_uploaded_file(). Теоретически можно использовать обычные функции копирования и перемещения. Но это не безопасно, потому что даёт возможность злоумышленнику получить доступ к другим файлам сайта. Поэтому лучше применять указанную функцию. Она работает только с файлом, который действительно загружен пользователем.

move_uploaded_file (временный адрес, новый адрес)

Создадим папку для файлов пользователя. Назовём её userfiles и расположим в папке, где находится скрипт.

Теперь переместим в созданную папку загруженный файл. Для этого добавим в скрипт следующий код:

4
5
6
$take = $_FILES['myfile']['tmp_name'];
$name = $_FILES['myfile']['name'];
move_uploaded_file($take, 'userfiles/'.$name);

Желательно проверять, успешно ли прошла загрузка. Для этого есть два способа. После загрузки во временную папку можно проверять код ошибки. Если это 0, значит загрузка удалась. Также можно проверить работу функции move_uploaded_file(), которая возвращает true при успешном перемещении. Хотя бы одну из этих проверок нужно производить.

Чтобы пользователь мог отправить сразу несколько файлов, нужно изменить форму отправки. Есть два варианта такой формы: указать тэгу <input>, отправляющему файл, атрибут multiple или добавить в форму несколько тэгов <input>. Второй вариант более предпочтителен, потому что так пользователь точно понимает, как добавить несколько файлов. Кроме того, можно легко ограничить их количество. Поэтому мы рассмотрим этот вариант. Изменим форму так, чтобы в форме было несколько тэгов <input> Установим им разные имена.

HTML код:

10
11
<input type="file" name="myfile1">
<input type="file" name="myfile2">

На сервере нужно создать цикл, который перемещает все файлы в нужную папку. Теперь скрипт takefile.php будет выглядеть так:

takefile.php:

3
4
5
6
7
8
9
10
11
foreach ($_FILES as $n => $newfile)
  {
  if ($newfile['error']==0)
    {
    $take = $newfile['tmp_name'];
    $name= $newfile['name'];
    move_uploaded_file($take, 'userfiles/'.$name);
    }
  }