Загрузка файлов на сервер
Автор: Бардин
Павел
Здесь будет рассмотрена загрузка файлов
на сервер по протоколу HTTP. Рассмотрим
два варианта конфигурации PHP:
- register_globals=On - все
параметры передаваемые скрипту,
автоматически становятся глобальными
переменными.
- register_globals=Off -
параметры передаваемые скрипту
заносятся в массивы $_GET, $_POST, $_FILES, $_COOKIE, ...
Upload файлов при register_globals=On
Напишем HTML форму для отправки файла на
сервер.
Содержание формы (файл upload.html):
<html>
<body>
<FORM ENCTYPE="multipart/form-data" ACTION="myup.php" METHOD=POST>
Выберете файл: <INPUT NAME="myfile" TYPE="file">
<INPUT TYPE="submit" VALUE="Загрузить">
</FORM>
</body>
</html>
После того как пользователь выбрал имя
файла и нажал кнопку Загрузить, PHP
помещает загружаемый файл во временную
директорию указанную в параметре upload_tmp_dir
файла php.ini. В этой директории этот файл
будет храниться только во время запроса!
После запроса PHP удалит этот временный файл.
Поэтому загружаемый файл нужно куда-нибудь
переместить (если он вам понадобиться в
дальнейшем). Явно удалить временный файл
можно функцией unlink(string filename).
Здесь рассмотрим загрузку текстового
файла и вывод его содержимого.
Скрипт обработки:
<?php
// Загрузка файлов на сервер
// Если register_globals=On
print("Имя файла на нашем сервере (во время запроса): ".$myfile."<br>");
print("Имя файла на компьютере пользователя: ".$myfile_name."<br>");
print("MIME-тип файла: ".$myfile_type."<br>");
print("Размер файла: ".$myfile_size."<br><br>");
// Получаем содержимое файла
$fp = fopen($myfile,"r");
$content = fread($fp, filesize($myfile));
fclose($fp);
// Вывод содержимого файла
print($content);
?>
Пояснения:
$myfile - имя временного файла, в котором
находятся загруженные данные;
Когда пользователь отправляет форму, PHP
автоматически определяет ещё несколько
переменных:
$myfile_name - имя файла на компьютере
компьютере пользователя;
$myfile_type - MIME-тип файла.
$myfile_size - размер файла в байтах.
При загрузке текстовых файлов переменная
$myfile_type = "text/plain", при загрузке
изображения gif переменная $myfile_type = "image/gif".
При register_globals=On можно пользоваться
массивом $_FILES[].
Upload файлов при register_globals=Off
В этом случае PHP формирует массив $_FILES[]. В
этом массиве храниться вся информация о
всех загружаемых файлах. В нашем случае
структура этого массива следующая:
$_FILES["myfile"]["tmp_name"] - Имя
временного файла
$_FILES["myfile"]["name"] - Имя файла на
компьютере пользователя
$_FILES["myfile"]["size"] - Размер файла
в байтах
$_FILES["myfile"]["type"] - MIME-тип файла
$_FILES["myfile"]["error"] - код ошибки.
PHP код для обработки формы:
<?php
// Загрузка файлов на сервер
// Если register_globals=Off
// Если upload файла
if(isset($_FILES["myfile"]))
{
$myfile = $_FILES["myfile"]["tmp_name"];
$myfile_name = $_FILES["myfile"]["name"];
$myfile_size = $_FILES["myfile"]["size"];
$myfile_type = $_FILES["myfile"]["type"];
$error_flag = $_FILES["myfile"]["error"];
// Если ошибок не было
if($error_flag == 0)
{
print("Имя файла на нашем сервере (во время запроса): ".$myfile."<br>");
print("Имя файла на компьютере пользователя: ".$myfile_name."<br>");
print("MIME-тип файла: ".$myfile_type."<br>");
print("Размер файла: ".$myfile_size."<br><br>");
// Получаем содержимое файла
$fp = fopen($myfile,"r");
$content = fread($fp, filesize($myfile));
fclose($fp);
// Вывод содержимого файла
print($content);
} // end of if 2
} // end of if 1
?>
При загрузке можно проверять
размер файла ($myfile_size) и если его размер
превышает требуемый, то вывод файла не
производить.
Значения $_FILES["myfile"]["error"]:
0 - ошибок не было, файл
загружен.
1 - размер загруженного файла превышает
размер установленный параметром upload_max_filesize
в php.ini
2 - размер загруженного файла превышает
размер установленный параметром MAX_FILE_SIZE в
HTML форме.
3 - загружена только часть файла
4 - файл не был загружен (Пользователь в
форме указал неверный путь к файлу).
Если вам необходимо сохранить
загруженный файл, то это можно сделать с
помощью функций:
- copy ( string source, string dest);
- move_uploaded_file ( string filename, string destination);
Функция copy() копирует файл source в место
назначения dest.
Функция move_uploaded_file() перемещает
загруженный файл filename в место
назначение указанное в параметре destination.
Ещё хочется отметить что при
одновременной загрузке нескольких файлов т.е.
когда HTML форма содержит:
<INPUT NAME="myfile1" TYPE="file">
<INPUT NAME="myfile2" TYPE="file">
<INPUT NAME="myfile3" TYPE="file">
массив $_FILES[] будет иметь
следующую структуру:
$_FILES["myfile1"]["tmp_name"] - Имя
временного файла 1
$_FILES["myfile1"]["name"] - Имя файла на
компьютере пользователя 1
$_FILES["myfile1"]["size"] - Размер файла
1 в байтах
$_FILES["myfile1"]["type"] - MIME-тип файла 1
$_FILES["myfile1"]["error"] - код ошибки
для файла 1.
$_FILES["myfile2"]["tmp_name"] - Имя
временного файла 2
$_FILES["myfile2"]["name"] - Имя файла на
компьютере пользователя 2
$_FILES["myfile2"]["size"] - Размер файла
2 в байтах
$_FILES["myfile2"]["type"] - MIME-тип файла 2
$_FILES["myfile2"]["error"] - код ошибки
для файла 2.
$_FILES["myfile3"]["tmp_name"] - Имя
временного файла 3
$_FILES["myfile3"]["name"] - Имя файла на
компьютере пользователя 3
$_FILES["myfile3"]["size"] - Размер файла
3 в байтах
$_FILES["myfile3"]["type"] - MIME-тип файла 3
$_FILES["myfile3"]["error"] - код ошибки
для файла 3.
это пример для одновременной загрузки
трёх файлов.
Таким же образом можно загружать и
двоичные файлы, например файлы картинок gif,
jpeg и т.д.
У меня все двоичные файлы загружались без
повреждений (без глюков), но по словам
Дмитрия Бородина (http://php.spb.ru)
возможно, что при загрузке двоичных файлов
у вас возникнут проблемы. Файлы будут
загружаться с перекодировкой.
Вот часть статьи "Как
делать UPLOAD файлов на сервер и о возможных
глюках" сайта http://php.spb.ru,
которая возможно поможет вам устранить
причину проблемы:
ЦИТИРОВАНИЕ
Попробуйте аплодить таким способом на сервер бинарные файлы. Скорее всего файлы окажутся "битыми": фотки не будут показываться, программы не
запустятся, архивы не распакуются. Текстовые файлы (почти точно) не
повредятся. Дело в том, что Русский Апач (ваш веб-сервер) перекодирует все подряд. Например, символ с кодом
0х00 он заменяет на пробел (символ с кодом
0х20). Чтобы выключить эту ненужную перекодировку, допишите в файл
httpd.conf из каталога Апача (/usr/local/apache) следующие строки. Если у вас нет доступа к этому файлу и админ сервера не может сделать это за вас, ткните его в эти строки.
<Location />
CharsetRecodeMultipartForms Off
</Location>
Строку CharsetRecodeMultipartForms Off можно добавлять в разные места (один раз). Если вы совсем начинающий пользователь и не решите сами, куда писать эту строку, будьте аккуратнее при решении задачи методом тыка.
|