Принципы загрузки файлов
Загрузка файла на сервер может быть выполнена как с помощью веб-формы, расположенной на странице сайта, так и прямым программным запросом. Для PHP-интерпретатора способ передачи файла не имеет значения. Спецификация HTTP-протокола приводит эти операции к единообразному виду.Любой загружаемый файл будет помещен в специальную директорию для временного хранения, а связанная с ним информация добавлена в суперглобальный массив $_FILES. Если не переместить файл в другое место, после завершения скрипта произойдет его бесследное удаление. Директория временного хранения определяется настройкой upload_tmp_dir конфигурационного файла php.ini.
Суперглобальный массив $_FILES
Если вместе с текущим запросом были загружены файлы, PHP-интерпретатор автоматически заполнит суперглобальный массив $_FILES соответствующей информацией. Его структура довольно проста. Элементы массива соответствуют именам параметров HTTP-запроса. Например, ваша веб-форма содержит поле загрузки файла с атрибутом «name="upload-file"». В таком случае информация будет добавлена в $_FILES['upload-file'].Содержимое массива $_FILES:
- $_FILES['поле-запроса']['name'] — реальное имя файла, которое он имел до отправки.
- $_FILES['поле-запроса']['size'] — размер загруженного файла в байтах.
- $_FILES['поле-запроса']['type'] — MIME-тип файла.
- $_FILES['поле-запроса']['tmp_name'] — содержит имя файла, которое назначил ему интерпретатор при размещении во временную директорию;
- $_FILES['поле-запроса']['error'] — код ошибки, возникшей при загрузке. Если всё нормально, элемент будет иметь значение «0».
Заметка!
Существует одно требование к HTML-разметке полей, осуществляющих множественный выбор и загрузку файлов. Их атрибут name должен быть составлен следующим образом «name="имя-атрибута[]"». Если вы опустите конструкцию [], PHP обработает только один файл.
Существует одно требование к HTML-разметке полей, осуществляющих множественный выбор и загрузку файлов. Их атрибут name должен быть составлен следующим образом «name="имя-атрибута[]"». Если вы опустите конструкцию [], PHP обработает только один файл.
{reklama}
Перемещение загруженного файла
Как говорилось выше, загружаемые файлы размещаются во временной директории сервера и автоматически удаляются PHP-интерпретатором после выполнения текущего запроса. Их можно сохранить, переместив в другое место. Использовать стандартные функции copy() или rename() крайне нежелательно.Для перемещения загруженных файлов существует специальная функция move_uploaded_file(). Она принимает два обязательных строковых параметра. Первый указывает имя файла во временной директории, а второй - путь назначения. Функция возвращает true в случае успеха и false, если произошла ошибка.
С помощью функции is_uploaded_file() вы можете проверить, является ли файл загруженным в текущем запросе. Она принимает всего один параметр — имя файла, а возвращает результат логического типа.
//Определяем место сохранения загруженного файла и его имя
$destination = $_SERVER['DOCUMENT_ROOT']. '/uploads';
$fileTempName = $_FILES['parameter']['tmp_name'];
if (is_uploaded_file($fileTempName)) {
//Проверяем тип файла и меняем его имя в соответствии
$newFilename = $destination .'/user';
switch ($_FILES['parameter']['type']) {
case 'application/pdf':
$newFilename .= '-document.pdf';
break;
case 'video/mp4':
$newFilename .= '-video.mp4';
break;
default:
echo 'Файл неподдерживаемого типа';
exit;
}
//Перемещаем файл из временной папки в указанную
if (move_uploaded_file($fileTempName, $newFilename)) {
echo 'Файл сохранен под именем '. $newFilename;
} else {
echo 'Не удалось осуществить сохранение файла';
}
} else {
echo 'Файл не был загружен на сервер';
}
Важно!
PHP позволяет изменять местоположение загруженных файлов с помощью обычных функций копирования или перемещения. Однако это довольно опасно. Существует ряд ухищрённых атак, основанных на таком недальновидном подходе.
PHP позволяет изменять местоположение загруженных файлов с помощью обычных функций копирования или перемещения. Однако это довольно опасно. Существует ряд ухищрённых атак, основанных на таком недальновидном подходе.
Для перемещения и проверки существования загруженных файлов всегда используйте функции move_uploaded_file() и is_uploaded_file(). В процессе выполнения они осуществляют расширенные проверки и автоматически отсеивают ряд распространенных атак.
Пример загрузки файла на сервер
Ниже приводится пример PHP-скрипта. Если он вызывается в первый раз, либо в текущем запросе отсутствует загрузка файла, пользователю выводится форма. При загрузке, файл перемещается в корневую директорию сайта, а пользователю показывается информация, связанная с ним. Обрабатываются только изображения в форматах jpg, jpeg и png.<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Простая форма загрузки файла</title>
</head>
<body>
<?php if (!isset($_FILES['upload']['tmp_name'])) : ?>
<!-- Данная форма будет показана, если не было загрузок -->
<form method="POST" enctype="multipart/form-data">
<input name="upload" type="file">
<input type="submit" value="Отправить">
</form>
<?php else: ?>
<?php
$newFilename = $_SERVER['DOCUMENT_ROOT']. '/uploaded-file';
$uploadInfo = $_FILES['upload'];
//Проверяем тип загруженного файла и дописываем расширение
switch ($uploadInfo['type']) {
case 'image/jpeg':
$newFilename .= '.jpg';
break;
case 'image/png':
$newFilename .= '.png';
break;
default:
echo 'Файл неподдерживаемого типа';
exit;
}
//Перемещаем файл из временной папки в указанную
if (!move_uploaded_file($uploadInfo['tmp_name'], $newFilename)) {
echo 'Не удалось осуществить сохранение файла';
}
?>
<!-- Выводим разметку, содержащую информацию о файле -->
<img src="/<?php echo basename($newFilename) ?>">
<ul>
<li>Размер файла: <?php echo $uploadInfo['size'] ?>байт</li>
<li>Имя до загрузки: <?php echo $uploadInfo['name'] ?></li>
<li>MIME-тип: <?php echo $uploadInfo['type'] ?></li>
</ul>
<?php endif; ?>
</body>
</html>