Сохранение изображений в базе данных: все "за" и "против"
Как внести (вписать) изображение в ячейку базы данных
Как вывести изображение из базы данных
Сохранение изображений в базе данных: все "за" и "против"
Рано или поздно при создании компонентов возникает вопрос: где и как удобнее хранить изображения? Существует три варианта:
- хранить в общей папке images сайта;
- хранить в папке images компонента;
- хранить в базе данных.
Какой вариант лучше, какой выбрать? Это уже решать вам.
Одним из лучших вариантов является хранение основных изображений в общей папке images сайта; в этом случае они будут легко доступны независимо от того, какой компонент или модуль их выводит на экран. А вот в папке images компонента лучше всего хранить вспомогательные изображения, относящиеся исключительно к данному модулю - так будет проще и удобнее с ними работать, а так же в случае необходимости переносить компонент на другой сайт.
Что касается хранения изображений в виде кода в базе данных, то здесь важно помнить, что вывод изображения на страницу из базы данных займёт значительно больше времени, чем вывод из папки images; связано это с тем, что изображение, хранящееся в базе данных, проходит двойную кодировку, точнее, сначала кодируется в определённую кодировку (PHP-функция base64_encode), затем декодируется (data:image/jpeg;base64,) уже в обычный стандарт .jpg или .png (см. ниже). Соответственно, если у вас на странице присутствует только одно изображение, это ещё допустимо, но если их несколько, то лучше от такого способа хранения отказаться и использовать соответствующую папку на сайте, так как к повышенному времени ответа сервера поисковые системы относятся весьма отрицательно, а значит, такие страницы не попадают на первые страницы выдачи.
Как внести (вписать) изображение в ячейку базы данных
Если вы всё-таки решили хранить изображения в базе данных, то важно учитывать тип используемого для этих целей столбца. Ниже приведены возможные варианты при работе с БД MySQLi.
- TINYBLOB - максимальная длина 255 байт, сохраняется с однобайтовым префиксом, указывающим длину значения
- BLOB - максимальная длина 65535 байт, сохраняется с двухбайтовым префиксом, указывающим длину значения
- MEDIUMBLOB - максимальная длина 16777215 байт, сохраняется с трёхбайтовым префиксом, указывающим длину значения
- LONGBLOB - максимальная длина 4294967295 байт, сохраняется с четырёхбайтовым префиксом, указывающим длину значения
Для начала нужно создать в базе столбец с соответствующим типом; назовём его для примера img1. При создании укажите значение по умолчанию как "Нет".
Далее нужно обработать имеющееся изображение. К примеру, вы получили запрос от пользователя, переданный методом POST, содержащий файл изображения. Такой запрос содержит ассоциативный массив $_FILES, в котором находятся следующие данные:
- $_FILES['userfile']['name'] - имя файла на компьютере клиента (отправителя);
- $_FILES['userfile']['type'] - тип файла;
- $_FILES['userfile']['size'] - размер файла;
- $_FILES['userfile']['tmp_name'] - временное имя файла на сервере и путь к нему;
- $_FILES['userfile']['error'] - код возможной ошибки.
Далее нужно обработать запрос следующим образом:
1 if( !empty( $_FILES['mess_img_1']['name'] ) ) {
2 if (is_uploaded_file($_FILES['mess_img_1']['tmp_name'])) {
3 if ( $_FILES['mess_img_1']['error'] == 0 ) {
4 if( substr($_FILES['mess_img_1']['type'], 0, 5)=='image' ) {
5 $image_1 = file_get_contents( $_FILES['mess_img_1']['tmp_name'] );
6 $image_1 = addslashes($image_1);
7 }
8 }
9 }
10 }
Строка 1 проверяет, существует ли загруженный файл. Если файл существует, то строка 2 при помощи функции is_uploaded_file проверяет, был ли файл загружен при помощи HTTP POST. Это в какой-то степени обеспечивает безопасность загружаемого контента.
Строка 3 проверяет наличие возможной ошибки. Если ошибки нет (код 0), то строка 4 проверяет тип файла; для этого используется функция PHP substr, которая в данном случае отбрасывает всё содержимое переменной начиная с 6-го символа.
$_FILES['userfile']['type'] указывает тип файла изображения как image/jpeg, image/png и так далее; соответственно при помощи функции substr проверяется соответствие первых пяти символов, т.е. image.
В строке 5 при помощи функции file_get_contents выполняется запись полученного файла изображения (его временное название и временный адрес указаны в переменной $_FILES['mess_img_1']['tmp_name']) в переменную $image_1 в виде строки.
В строке 6 функция addslashes экранирует некоторые символы, имеющиеся в переменной $image_1 и снова их записывает в эту переменную, но уже со слешами. Экранируются символы ', ", \, NUL.
Обратите внимание: хотя функция addslashes в какой-то степени защищает систему от так называемых SQL-инъекций, но в PHP не рекомендовано применение данной функции для этой цели. Для обеспечения более надёжной защиты используйте дополнительный код для обработки передаваемых файлов. Подробнее читайте здесь.
Теперь в переменной $image_1 содержится изображение в виде строки, полностью подготовленное к внесению в базу данных. Внесение осуществляется точно так же, как и любой другой текст.
Как вывести изображение из базы данных
Вывод изображения из базы данных осуществляется довольно просто. В строке кода HTML, в теге <img> прописываем:
<img src="data:image/jpeg;base64,<?php echo base64_encode($image); ?>">
где $image - переменная, содержащая изображение в виде строки, полученное из соответствующей ячейки базы данных. Данное выражение, содержащееся в атрибуте src, указывает, что это изображение (image/jpeg), закодированное в base64. Обратите внимание: это не ссылка на изображение, это само изображение, вводимое сюда с помощью php-кода.
Теперь при открытии страницы, содержащей данный код, на ней в указанном месте будет выводится изображение.