Как отправить пользовательское изображение на Ваш сервер (php)

Если перед Вами встала задача отправить пользовательское изображение на свой веб-сервер, чтобы потом его как-то использовать (например, выводить в профиле пользователя, либо еще как-то), то в этом уроке я покажу Вам, как можно организовать такую отправку изображения при помощи php.
дополнительные материалы к урокам
Возможно, Вы уже отправляли на сервер различную пользовательскую информацию при помощи html-форм и php-сценариев. Если Вы занимались этим раньше – прекрасно. Но между тем, чтобы отправлять простые текстовые поля информации, заполненные пользователем, и отправкой целого файла с компьютера пользователя на Ваш веб сервер есть кое-какая разница.

Изображения являются двоичными данными и для чтения двоичного файла нужен несколько другой тип интерпретации. Однако, веб-браузеры замечательно приспособлены к работе с файлами изображений форматов JPEG, GIF или PNG и могут замечательно выводить их на экраны наших мониторов.

Итак, чтобы какое-либо из пользовательских изображений можно было увидеть на Вашем ресурсе, пользователь должен отправить это изображение на Ваш веб-сервер. А Ваша задача заключается в получении файла изображения сервером от клиента.

Давайте перейдем к практике!

Отправка пользовательского изображения на веб-сервер

Создание html-формы

1. Давайте для начала создадим html-документ. Я назову его «send_image.html».
Этот документ будет содержать html-форму, с помощью которой пользователь сможет выбрать файл для отправки его со своей машины на Ваш веб-сервер.

Сразу сделаю оговорку: форму в этом примере я создаю только для отправки файла (чтобы сосредоточить все внимание на этом и не путать Вас в других возможных полях), но на практике, конечно же такая форма может содержать столько полей, сколько вам нужно (такие как: имя, e-mail адрес и прочее).

Код нашей html-страницы будет выглядеть вот так:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<title>Отправка изображения на сервер</title>
</head>

<body>
<div id="content">
<h1>Отправляем изображение на сервер</h1>
<form action="send_img.php" method="post" enctype="multipart/form-data">
<fieldset>
<input type="hidden" name="MAX_FILE_SIZE" value="2000000">
<label for="user_pic">Отправка изображения:</label>
<input type="file" name="user_pic" size="30">
</fieldset>
<fieldset>
<input type="submit" value="Отправить изображение">
</fieldset>
</form>
</div>
</body>
</html>

 

Теперь разъясним данный код.

Документ имеет формат html5. К документу подключена таблица стилей, код которой я приведу ниже.

Теперь посмотрим на саму форму.

В качестве значения атрибута «action» мы передаем файл-обработчик «send_img.php», который мы также создадим далее и который будет выполнять все манипуляции с выбранным для отправки файлом.

Очень важным составляющим здесь является атрибут «enctype» в теге «form», а также значение типа «file» в теге «input». С помощью всего этого мы настраиваем форму не только на отправку текстовой информации, но и на отправку двоичного файла изображения.

Также Вы могли заметить еще один тег «input» (самый первый), он имеет скрытый тип, и Ваши пользователи его не увидят. Однако, он содержит в себе информацию о максимально допустимом размере изображения (в данном случае 2Мбайта). Это нужно для того, чтобы Вам на сервер не отсылали гигантские фото.

2. Теперь давайте создадим файл таблицы стилей и наполним его содержимым.

Для этого примера я использовала самые простые стили, просто для того, чтобы страница смотрелась более или менее прилично. Вы можете создать свои стили или на этапе обучения и тестирования воспользоваться теми, которые предлагаю я.

Итак, создайте файл «style.css» и сохраните его в том же каталоге, что и html-файл. Если будете сохранять в отдельной папке, то исправьте путь к файлу в html-документе.

Содержимое файла таблицы стилей следующее:

body{width:400px; margin:0 auto; background:#F8F4B6;}
label{display: block; float: left; width: 300px;
  padding: 5px 10px; margin: 18px 0 0; text-align: right;
  font-family:Georgia, "Times New Roman", Times, serif; font-style:italic; font-weight:bold;}
#submit{float:right; margin:5px 50px 10px 0;}
input{text-align:center;}

 

В итоге, если сейчас открыть наш html-документ в браузере, то можно увидеть следующее:

разметка для формы отправляющей изображения

1. Если Вы хотите тестировать Ваш будущий php-код и работу с базами данных с локального компьютера, то Вам необходимо будет установить Денвер.

2. Если Вы тестируете Ваш код с локального компьютера с установленным на него Денвером, то не забывайте, что, чтобы все работало корректно файл в браузере нужно запускать следующим образом: в командной строке браузера нужно прописать localhost/имя папки, в которой расположен файл/имя файла и нажать клавишу «Enter».

Иначе, если Вы просто запустите файл в браузере, щелкнув по нему два раза мышью, в дальнейшем протестировать php-код не получится.

Создаем php-сценарий

1. Мы подготовились к основной работе и сейчас настало время самого главного – мы будем создавать файл-обработчик.

Для начала создайте файл «send_img.php» и сохраните его в том же каталоге, что и основной html-файл.

Откройте файл «send_img.php» и пропишите в нем следующие строки:

<?php

?>

 

Между этим двумя тегами (открывающим и закрывающим тегами php) и будет располагаться весь наш код, который мы начнем писать прямо сейчас.

2. Так как мы собираемся не просто копить пользовательские изображения, а, вероятно, впоследствии использовать их на своем ресурсе, то после того, как мы их получим и сохраним в определенном месте на своем веб сервере, нам еще и нужно будет где-то хранить пути к ним. И вероятнее всего, хранить путь до изображения мы будем в базе данных.

Поэтому первое, что нужно сделать – это соединиться с базой данных.

У Вас уже должна быть создана база данных, с которой Вы собираетесь работать. А также у Вас должно быть имя пользователя и пароль для соединения с этой базой. На веб-сервере Вы генерируете эти данные при добавлении новой базы данных. Если Вы не знаете, как это сделать в Денвере (в случае, если Вы тестируете код на локальной машине), то можете прочитать об этом в моей статье Создание базы данных MySql.

Итак, соединяемся с базой. Для этого пропишите в Вашем php-файле следующий код. Обратите внимание, что данные в скобках у Вас должны быть свои (кроме localhost ), это должно быть Ваше имя пользователя, пароль и имя базы, с которой соединяетесь.

mysql_connect("localhost", "anna", "12345")//параметры в скобках ("хост", "имя пользователя", "пароль")
or die("<p>Ошибка подключения к базе данных! " . mysql_error() . "</p>");

mysql_select_db("new_db")//параметр в скобках ("имя базы, с которой соединяемся")
 or die("<p>Ошибка выбора базы данных! ". mysql_error() . "</p>");

 

На этом этапе нужно протестировать код, чтобы убедиться, что Вы соединились с базой успешно. Для этого откройте html-страницу в браузере и попробуйте нажать на кнопку отправки.

Если все хорошо, то после отправки Вы просто увидите белый экран, а если произошла ошибка, то Вы увидите сообщение об этой ошибке, подобное вот этому:

ошибка соединения с базой данных

Если Вы увидели сообщение об ошибке, то проверьте правильность введенных данных: имени пользователя, пароля, имя базы. А также проверьте правильность синтаксиса.

Если ошибок нет, тогда идем дальше.

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

Нам нужно как-то обрабатывать все эти ошибки и выводить соответствующие сообщения для пользователя.

Для этого мы сейчас напишем функцию, которую в дальнейшем будем использовать. Эта функция будет принимать 2 параметра: первый параметр будет общим сообщением о проблеме, а второй параметр будет конкретизировать проблему, обращая внимание на то, чем она вызвана. При запуске такая функция будет останавливать выполнение сценария и выводить соответствующие сообщения об ошибках.

Итак, добавьте в свой код следующие строки:

function handle_error($user_error_message, $system_error_message)
 {die ($user_error_message ." " . $system_error_message); };

 

Теперь добавим пару переменных, которые нам понадобятся.

Первая переменная с именем «upload_dir» поможет нам определить каталог, в котором в последствии мы будем сохранять отправленные изображения. В ее значении в кавычках Вы должны прописать путь до папки, в которой собираетесь сохранять изображения. Если у Вас еще нет такой папки, то самое время ее создать в Вашей файловой системе. Имейте в виду, что в этом примере я тестирую код с помощью Денвера на локальной машине, и моя папка для изображений лежит в том же каталоге, что и php-файл. Поэтому мне достаточно в значении переменной прописать «user_images/». Вы должны исходить из своей файловой структуры, а также из того, как Вы задаете пути к файлам.

Вторая переменная будет содержать имя поля, которое мы указывали в атрибуте «name» в html-файле, для тега «input», отвечающего за отправку файла.

Таким образом к нашему коду можно добавить пару новых строк:

$upload_dir = "user_images/";
 $image_fildname = "user_pic";

 

При отправке изображения могут возникнуть разные ошибки (изображение может быть не выбрано, не отправилось полностью, имеет слишком большой размер).

Для каждого конкретного случая, нам нужно вывести соответствующее сообщение. Чтобы подготовиться ко всем этим ситуациям, нам нужно создать массив, который мы самостоятельно и пронумеруем. Этот массив будет содержать возможные ошибки.

Добавьте следующие строки к Вашему коду:

$php_errors = array(1 => 'Превышен мах. размер файла, указанный в php.ini',
 2 => 'Превышенм мах. размер файла, указанный в форме html',
 3 => 'Была отправлена только часть файла',
 4 => 'Файл для отправки не был выбран');

 

Мы полностью подготовились, теперь переходим к действиям.

4. Первое, что мы сделаем – это проверим, не произошло ли ошибок во время отправки изображения. Здесь нам понадобится только что созданный массив и функция, которую мы написали ранее.

Когда ведется работа с файлами, интерпретатор php создает массив «$_FILES». В этом массиве ключом служит имя Вашего поля (переменная «$image_fildname») и таким образом этот массив связывается с отправляемым Вами изображение. Также этот массив содержит не только информацию о файле, но и о любых ошибках, которые могут произойти во время отправки. Частицей этой информации является элемент «$_FILES[$image_fildname][‘error’]», который возвращает «0», если отправка была успешной и число отличное от нуля в противном случае (именно поэтому созданный нами массив мы нумеровали с единицы, а не с нуля).

И теперь нам остается проверить возвращает ли это поле ноль. Если да, то проблем нет. А если возвращает другое число, то нужно вывести сообщение, какая именно проблема возникла (здесь нам поможет наша функция «handle_error»).

Итак, добавьте в Ваш файл следующий код:

//Проверка на ошибки при отправке
$_FILES[$image_fildname]['error'] == 0
or handle_error ("Серверу не удается получить Ваше изображение<br>" , $php_errors[$_FILES[$image_fildname]['error']]);

 

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

проверка на ошибки при отправке файла на сервер

Теперь нужно проверить, действительно ли то, что отправляет пользователь является изображением. Сделать это можно при помощи специальной функции «getimagesize». Проверка осуществляется следующим образом:

//Действительно ли отправляемый файл изображение. Проверка
@getimagesize($_FILES[$image_fildname]['tmp_name'])
or handle_error("<p> Вы выбрали файл, который не является изображением<br>", $_FILES[$image_fildname]['tmp_name'] ." не является изображением");

 

Попробуйте вместо изображения отправить, например, текстовый файл, и Вы увидите примерно следующее.

проверка: какой файл отправляется

Также попробуйте протестировать и отправить нормальный файл. Если отправка прошла успешно, то Вы увидите только белый экран.

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

У Вас уже должна быть создана папка, путь к которой Вы прописали в переменной «upload_dir».

В первую очередь, перед тем, как перемещать файл нам нужно сформировать для него уникальное имя.

Для этого сначала создадим переменную «now», в которой будет содержаться текущее время.

Далее, прямо в цикле while мы создадим переменную «upload_filename», которая будет содержать в себе значение переменной «upload_dir» (путь до нашей папки для изображений) плюс текущее время, дефис и исходное имя пользовательского файла. Так мы получаем уникальное имя для файла.

Цикл будет запускаться, только если используется уже используемое имя файла. Если это так, то значение переменной «now» увеличивается, и попытка повторяется.

Я также добавила вывод на экран значение переменной «upload_filename», чтобы после отправки мы могли видеть путь до файла и его уникальное имя.

На этом этапе добавьте в свой файл следующий код:

$now = time();
while(file_exists($upload_filename = $upload_dir . $now . '-' . $_FILES[$image_fildname]['name'])){
	$now++;
}
echo $upload_filename;

 

Итак, уникальное имя для файла мы сделали. А теперь нужно переместить его в нужную папку. Здесь нам поможет функция «move_uploaded_file». Добавьте следующий кусок кода в Ваш файл:

@move_uploaded_file($_FILES[$image_fildname]['tmp_name'], $upload_filename)
or handle_error("возникла проблема при сохранении Вашего изображения в его постоянном месте <br>",
"ошибка, связанная с правами доступа при перемещении файла в {$upload_filename}");

 

А теперь протестируйте отправку файла. Если все пройдет успешно, то на экране Вы увидите путь до Вашего файла, а в подготовленной для него папке должен появиться и он сам.

Если Вы получили сообщение об ошибке внимательно проверьте весь код.

отправить пользовательское изображение на сервер

6. Осталось только добавить путь к изображению в базу данных, чтобы Вы дальше могли использовать это изображение на своем ресурсе.

Я создала для этого примера отдельную таблицу базы данных «user_image» с двумя полями: поле для идентификатора («id») и поле для записи пути к изображению («picture» — тип varchar).

Исходя из всего этого вставить путь в таблицу базы данных мы можем вот так:

$insert_sql = "INSERT INTO user_image SET picture='$upload_filename'";
mysql_query($insert_sql);

 

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

вставляем путь к изображению в базу данных

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

Жду Ваших комментариев и не забывайте делиться этим уроком с Вашими друзьями с помощью кнопок социальных сетей.

Подписывайтесь на обновление блога, потому что в этом году будет много всего интересного.

Успехов Вам, хорошего настроения и бодрого начала года.

Leave a Reply