belarusweb.net
© Петр Романовский Минск, 2016-2017.



belarusweb.net

Основы создания сайтов...
PHP+MySQL >>>
                          Учебник Задачник Справочник

10.3. Загрузка пользовательских файлов на сервер

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

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">	
	<title>Загрузка одиночных файлов</title>
</head>
<body>
	<form action="example_10_8.php" method="POST" enctype="multipart/form-data"> 
		<input type="hidden" name="MAX_FILE_SIZE" value="3000000">
		Загрузите аватарку (не более 3Мб):<br><br>
		<input type="file" name="userFile"><br><br>
		<button type="submit" name="submit" value="send">Отправить</button>
	</form>
</body>
</html>

Пример 10.7. Код формы с полем для загрузки одиночных файлов на сервер

Скрытое поле должно предшествовать полю для выбора файла. Его атрибуты name = "MAX_FILE_SIZE" и value = "30000" задают максимально допустимый размер загружаемого файла. Рекомендуется всегда использовать данные параметры, т.к. это предотвращает ненужное ожидание пользователей при передаче огромных файлов только для того, чтобы узнать, что файл слишком большой и его передача не состоялась. Конечно, обойти это ограничение на стороне браузера достаточно просто, следовательно, не стоит полагаться на то, что все файлы большего размера будут блокированы при помощи этой возможности. Однако на сервере настройки касательно максимального размера загружаемых файлов обойти практически невозможно.

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

Следует отметить, что для отправки файлов нужно обязательно указывать значение атрибута enctype = "multipart/form-data", вместо значения enctype = "application/x-www-form-urlencoded" элемента 'form', иначе загрузка файлов на сервер выполняться не будет.

После загрузки файла на сервер всю информацию о нем можно узнать из глобального массива $_FILES:

Использование суперглобального массива $_FILES показано в примере 10.8.

<?php
	//Предполагается, что файл был успешно загружен
	$userFile = $_FILES['userFile']['name'];
	echo 'Имя вашего файла: '.$userFile.'<br>';

	$userFileType = $_FILES['userFile']['type'];
	echo 'Тип вашего файла: '.$userFileType.'<br>';
	
	$userFileSize = $_FILES['userFile']['size'];
	echo 'Размер вашего файла: '.$userFileSize.' байт'.'<br>';
	
	$userFileTmp = $_FILES['userFile']['tmp_name'];
	echo 'Временное имя файла на сервере: '.$userFileTmp.'<br>';
	
	$userFileError = $_FILES['userFile']['error'];
	echo 'Код ошибки: '.$userFileError.'<br>';
?>

Пример 10.8. Обработка данных, переданных на сервер формой примера 10.7

Если нужно загрузить несколько файлов, то можно либо использовать в поле для отправки файлов атрибут multiple (см. пример 10.9), либо не одно, а несколько соответствующих элементов 'input'. При этом, если размер какого-либо из файлов превысит значение "MAX_FILE_SIZE", он загружен не будет. Однако это не повлияет на загрузку остальных файлов, поэтому желательно сообщать о такой ситуации пользователю выводом соответствующего сообщения.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">	
	<title>Загрузка нескольких файлов</title>
</head>
<body>
	<form action="example_9_10.php" method="POST" enctype="multipart/form-data"> 
		<input type="hidden" name="MAX_FILE_SIZE" value="3000000">
		Загрузите аватарки (не более 3Мб каждая):<br><br>
		<input type="file" name="userFile[]" multiple><br><br>
		<button type="submit" name="submit" value="send">Отправить</button>
	</form>
</body>
</html>

Пример 10.9. Код формы с полем для загрузки нескольких файлов на сервер

При использовании атрибута multiple в качестве значения атрибута name нужно использовать массив, иначе на сервере мы сможем получить данные только о последнем загруженном файле. После загрузки файлов на сервер доступ к ним может быть получен, опять же, через суперглобальный массив $_FILES, с учетом того, что файлам в массиве будут назначены числовые ключи согласно порядку их отправки (см. пример 10.10).

<?php
	//Будем считать, что как минимум один файл был загружен
	//Выводим информацию о первом из загруженных файлов
	$userFile = $_FILES['userFile']['name'][0];
	echo 'Имя вашего файла: '.$userFile.'<br>';

	$userFileType = $_FILES['userFile']['type'][0];
	echo 'Тип вашего файла: '.$userFileType.'<br>';
	
	$userFileSize = $_FILES['userFile']['size'][0];
	echo 'Размер вашего файла: '.$userFileSize.' байт'.'<br>';
	
	$userFileTmp = $_FILES['userFile']['tmp_name'][0];
	echo 'Временное имя файла на сервере: '.$userFileTmp.'<br>';
	
	$userFileError = $_FILES['userFile']['error'][0];
	echo 'Код ошибки: '.$userFileError.'<br>';
?>

Пример 10.10. Обработка данных, переданных на сервер формой примера 10.9

В случаях, когда необходимо по-разному ограничить размеры загружаемых файлов, следует выбирать второй вариант, используя несколько полей для отправки файлов и указывая перед каждым из них скрытое поле с требуемым ограничением размера (см. пример. 10.11). Кроме того, к файлам можно будет обращаться по их ключам, хотя можно поступить и предыдущим способом, просто объявив общий массив.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">	
	<title>Загрузка нескольких файлов</title>
</head>
<body>
	<form action="example_10_12.php" method="POST" enctype="multipart/form-data"> 
		Загрузите фото (не более 1Мб):
		<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
		<input type="file"  name="file_1"><br><br>
		Загрузите аватарку (не более 50Кб):
		<input type="hidden" name="MAX_FILE_SIZE" value="50000">
		<input type="file"  name="file_2"><br><br>
		<button type="submit" name="submit" value="send">Отправить</button>
	</form>
</body>
</html>

Пример 10.11. Код формы с несколькими полями загрузки файлов

<?php
	//Будем считать, что оба файла были загружены
	//Выводим информацию о результатах загрузки файлов
	$fileName_1 = $_FILES['file_1']['name'];
	echo 'Имя вашего файла: '.$fileName_1.'<br>';

	$fileError_1 = $_FILES['file_1']['error'];
	echo 'Код ошибки: '.$fileError_1.'<br>'.'<br>';
		
	$fileName_2 = $_FILES['file_2']['name'];
	echo 'Имя вашего файла: '.$fileName_2.'<br>';

	$fileError_2 = $_FILES['file_2']['error'];
	echo 'Код ошибки: '.$fileError_2.'<br>'.'<br>';
?>

Пример 10.12. Обработка данных, переданных на сервер формой примера 10.11

В процессе загрузки файлов на сервер они помещаются во временную папку, которая задается в настройках конфигурационного файла php.ini (подробно рассмотрим позже). Для того, чтобы переместить файл из временной папки в нужное место, нужно использовать функцию move_uploaded_file(), которая проверяет, является ли файл загруженным на сервер по протоколу HTTP POST, и в случае удачи перемещает загруженный файл в новое место, возвращая при этом true (см. пример 10.13). Если же перемещение по каким-либо причинам невозможно, функция вернет false (см. раздел 'Расширения для работы с файловой системой' официального справочника).

<?php
//Переместим файл, загруженный при помощи формы примера 10.7, в папку loaded_files
//Сохраним путь к файлу во временной папке в переменной
$userFileTmp = $_FILES['userFile']['tmp_name'];

//Сохраним в переменной исходное имя загруженного файла
$file_name = $_FILES['userFile']['name'];
//Путь построим от корня сайта '/' и заменим временное имя файла обратно на свое
$my_dir="/loaded_files/{$file_name}";

//Если файл будет перемещен, функция вернет true
if(move_uploaded_file($userFileTmp, $my_dir)){
    echo "Файл корректен и был успешно перемещен.";
}else{
    echo "Файл не был перемещен!";
}
?>

Пример 10.13. Перемещение загруженных файлов из временной папки

Если требуется переместить сразу несколько файлов, загруженных при помощи поля с атрибутом multiple (см. пример 10.9 и пример 10.10), можно воспользоваться, например, циклом foreach, повторив процедуру перемещения для всех элементов массива.

Комментарии (0)
Петр Романовский
1. Приветствуются комментарии, которые содержат дополнения к материалу текущей страницы, а также ваши ответы на вопросы других пользователей.
2. Если вам что-то непонятно - спрашивайте, не забывая написать, что именно и с какого места.
Показаны все комментарии
Чтобы оставить свой комментарий, авторизуйтесь, пожалуйста!    
     
belarusweb.net © Петр Романовский, Минск, 2016-2017.
Связаться с автором
Наверх