и причём тут phpMyAdmin ?

хранить изображения в БД — тупо!
Храните картинки в какой-то папке! А в базе храните только имя файла! Можно вообще даже не хнарить ничего.. .Т. е. имя файлов делать в виде ‘image_’.$id.’.jpg’ — и если файл для указанного $id есть в папке, выводить его в вопросе.. .

PHP, MySQL, JavaScript, AJAX, HTML и CSS

Хранение изображений в базе данных MySQL

Для хранения изображений в базе данных MySQL необходимо определить одно из полей таблицы как производное от типа BLOB. Сокращение BLOB означает большой двоичный объект. Тип хранения данных BLOB обладает несколькими вариантами:

  • TINYBLOB — может хранить до 255 байт
  • BLOB — может хранить до 64 килобайт информации
  • MEDIUMBLOB — до 16 мегабайт
  • LONGBLOB — до 4 гигабайт

Соответсвенно, для хранения изображений нам надо создать таблицу images с двумя полями:

  • id — уникальный ID изображения
  • content — поле для хранения изображения

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

Обработчик формы — файл putimage.php:

Извлечь сохраненный файл изображения можно следующим образом (файл image.php):

Чтобы вывести изображение в HTML-документе, делаем так:

И последнее: графические файлы иногда имеют довольно большой размер, убедитесь, что настройки сервера позволяют работать с таким объемом данных. В файле php.ini это директивы post_max_size — определяет максимальный объем данных передаваемых методом POST, и upload_max_filesize — определяет максимальный размер загружаемого файла. Так же проверьте, позволяют ли настройки MySQL обрабатывать запросы с большим объемом данных (директива max_allowed_packet файла my.ini).

Комментариев: 59

еще бы примеры, когда хранить картинки в базе лучше чем просто на диске

admin:

art, хранить графические файлы в базе данных — не самое удачное решение. Ведь это создает дополнительную нагрузку на сервер БД.

Когда мы сохраняем в базе данных каталог продукции, заказы в Интернет-магазине — то это вполне оправдано. Потому как альтернативный вариант — сохранять всю информацию в файлах. И работать с файлами напрямую. Но базы данных для того и созданы, чтобы избавить нас от этой рутины. Ведь в конечном итоге, все данные все равно сохраняются в файлах, хотя мы и говорим, что “данные хранятся в БД”. БД — это некий уровень абстракции, который здорово облегчает жизнь.

Почему тогда хранят файлы в базе данных? Дело в том, что на некоторых хостингах на объем дискового пространства есть ограничения, в то время как на размер БД — нет. Подчеркиваю — на некоторых. В этом случае, чтобы не выйти за пределы дисковой квоты прибегают к такой хитрости — хранят файлы в БД. В противном случае смысла в этом нет.

Владимир Лапшин:

“SELECT *” в реально работающем приложении не самая хорошая идея. Лучше все-таки перечислять нужные поля. Точно помогает, когда в таблицу приходится добавить еще какое-то поле.

admin:

“SELECT *” в реально работающем приложении не самая хорошая идея.

Согласен, сам читал об этом, но частенько забываю. Здесь это тем более актуально — нам нужно выбрать всего одно поле. Исправил.

Анатолий:

Здравствуйте. Помогите начинающему. Загрузка картинки в базу идет нормально (вроде бы), т.е. объем загруженного файла (8кб) соответствует объему картинки, но плучить изображение обратно я не могу. В приведенном вами файле image.php — $_GET — не существует. Я малость его изменил — убрал лишние пока проверки — в результате, файл выводится, но не в виде картинки, а в виде текста-абракадабры.
Привожу свой вар. подскажите где ошибка, если знаете.

// Отсылаем браузеру заголовок, сообщающий о том,
//что сейчас будет передаваться файл изображения
header ( "Content-type: image/*" ) ;
include_once ‘conf4b.php’ ; //подключаем базу

//Вывод изображения из БАЗЫ, загруженного из формы
$query = "SELECT content FROM image " ;
// Выполняем запрос и получаем файл
$res = mysql_query ( $query ) ;
$image = mysql_fetch_array ( $res ) ;
echo $image [ ‘content’ ] ;
//выводится пустой квадратик

mysql_close ( $connect ) or die ( "not razriva" ) ;
print "соединение разорвано" ;
?>

admin:

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

уже является ошибкой. Браузер считает строку “соединение разорвано” частью изображения.

Анатолий:

Я полагал, что перед header нельзя делать какой-либо вывод.
Впрочем, я убрал принт, оставил только одно echo — результат тот же.

admin:

Перед заголовками, разумеется, не должно быть вывода. Сервер и браузер общаются между собой при помощи заголовков. В данном случае ты отправляешь браузеру заголовок “Content-type: image/*”, сообщающий браузеру, что ВСЕ ДАЛЕЕ будет картинка. Но вместе с картинкой отправляешь еще и текст. По поводу того, почему не работает — причин может быть воз и маленькая тележка:
1. скрипт для коннекта к БД содержит после закрывающего тега ?> какой-нибудь вывод (например, пробел или перевод строки)
2. пробел или пустая строка перед открывающим тегом 8 Октябрь 2008, 23:08

Анатолий CMX:

Спасибо! То что нужно! Все работает без правок и добавлений. Как семпл очень полезно и информативно!

От себя могу добавить, что хранение изображений в базе данных актуально например когда:
1) используются каталоги изображений для шаблонов (например наборы иконок)
2) когда есть много мелких изображений, файлы которых “весят” очень мало, но самих файлов очень много. В базе будет занято ровно столько места сколько требуется, а не сектора диска под нефактический объем файла.

НО:
Если вы собрались делать фото галерею или каталог “крупных” изображений, то целесообразнее организовать каталог в виде папок и подпапок на диске, а уже ссылки на файлы можно хранить в базе! Т.к. при достаточно большом объеме файлов и их количестве, если хранить данные в базе, возрастет нагрузка на ресурсы сервера при обращении и получениии данных из базы.

не знаю толково или нет, но думаю что прокомментировал в тему!

Мне понравилось про () , люблю изощренные решения. но всё таки мне не понятно почему тот же пхп не сделал стандартную функцию для чтения бинарных изображений из БД. явно напрашивается такая штука.

victor:

Хранить изображения в базе очень удобно. Насчёт загрузки сервера — это миф. Использую MSSQL 2005 и RAID 5, база около 20Г.

admin:

victor, а в чем удобство-то? Какое реальное преимущество мы получаем, если изображение у нас в таблице БД, а не просто в директории?

victor:

В администрировании, бекап, безопасность, механизм построения галереи простой. То есть я имею введу необходимые действия удаления, изменение, добавления галерей и фото. Всё это элементарно организуется посредствам самой ДБ (cascade) и требует минимального кода. В случае хранения фото “на диске” алгоритм сильно усложняется, нужно выполнять множество проверок при выполнении операций с диском… MSSQL сильно отличается от MySQL , а именно структура хранения данных, не рискнул бы хранить в ней большое количество фото.

Дмитрий:

Убогое какое-то описание, а где в скрипте соединение с базой данных, выбор таблицы. Уж если описываете, так сделайте чтобы даже военным было понятно

Сергей:

при переходе с MSSQL на MySQL столкнулся с проблемой, select count(*) from image; (посчитать количество картинок в базе) на MySQL выполняется 25 сек, на MSSQL MySQL меньше секунды. в таблице 50000 картинок, 300MB.
это нормально для mysql? или я что-то не так делаю?

admin:

Сергей, здесь явно что-то не так. Не может быть, чтобы разница во времени выполнения была такой большой. Попробуйте задать свой вопрос на форумах
SQL.RU
SQLINFO.RU

Mujeek:

Преимущества хранения изображений в базе — на лицо… когда есть необходимость каскадного удаления данных, а изображения находится, например, на 3 уровне подчинённости удаляемой записи..

Mujeek:

вдобавок не нужны проверки существования в каталоге одноименного файла…

Mujeek:

Будут ли кэшироваться на клиенте изображения, полученные из базы данных,или при каждом открытии страницы все изображения закачиваются заново?

admin:

Mujeek, вообще, дело обстоит так
* Страницы передаваемые по POST никогда не сохраняются в кэш.
* Страницы запрашиваемые по GET и содержащие параметры (в URL присутствует ‘?’) не сохраняются в кэш, если не указано обратное.
Наш вызов скрипта картинки выглядит так
http://server.com/image.php? > а значит по правилам изображение не будет сохраняться в кэш (присутствуют параметры), но через заголовок можно управлять этим. Подробности здесь:
PHP и Web. Кэширование

Ренат:

Здравствуйте, хочу спросить, а средствами PHP можно вывести на экран вместе с картинкой ещё, к примеру, оформление сайта? Ну не только картинку на экран? Или это уже к JavaScript’y?

Mujeek:

И как получить увеличенную картинку в отдельном окне при клике на изображении?

hannibal:

Очень нужно. Подскажите как вывести несколько изображений из базы.

Максим:

Сделал, подобие примера. Точнее повторил все точно точно также но вот вывода картинки я не вижу.
Загружаеться но вывода нет.
В чем может быть проблема? картика 64кб, поле(блоб).

qip 439_810-757 Мучаюсь 2 день, прошу помощи.

admin:

И как получить увеличенную картинку в отдельном окне при клике на изображении?
onClick=”popupWin = window.open(this.href, ”, ‘location,w >

А если красиво — использовать готовое решение:
Плагин FancyBox для библиотеки jQuery

admin:

Максим, давайте обсудим это на форуме. Выкладывайте свой скрипт, посмотрим, в чем там проблема.

Евгений:

> при переходе с MSSQL на MySQL столкнулся с проблемой,
> select count(*) from image; (посчитать количество
> картинок в базе) на MySQL выполняется 25 сек, на
> MSSQL MySQL меньше секунды. в таблице 50000 картинок, 300MB.
> это нормально для mysql? или я что-то не так делаю?

Не так делаете. Зачем запрашивать все поля *?
Проще и быстрее будет SELECT COUNT(`id`) FROM `image`;

Sancho:

Sancho:

не пойму почему не передает полный текст

admin:

Sancho, а Вы о чем вообще говорите?

Ольга:

Скажите, что делать с хедером, если изображение мне нужно вывести в середине страницы и, естественно, заголовок уже выведен.
При инклюде image.php, вылезает ошибка — Warning: Cannot modify header information — headers already sent by (output started at Z:homelocalhostwwwxyxaindex.php:17) in Z:homelocalhostwwwxyxaimage.php on line 13
Как мне всё же вывести изображение из БД в index.php?
(И, мало ли у кого есть готовый пример для ресайза изображения ДО добавления его в БД — буду очень признательна. Хотелось бы из одной загружаемой человеком фотографии сделать превью и фото, к примеру 600х400 и поместить их в БД, причем учитывая, что просто уменьшение может оказаться не пропорциональным, если, к примеру, фото было 1200х1000)Спасибо.

admin:

если изображение мне нужно вывести в середине страницы и, естественно, заголовок уже выведен. При инклюде image.php, вылезает ошибка — Warning: Cannot modify header information
По-моему, в заметке четко написано: чтобы вывести изображение в HTML-документе, делаем так

Включать изображение на страницу с помощью include?! Даже не комментирую…

у кого есть готовый пример для ресайза изображения ДО добавления его в БД
Масштабирование изображений

Ольга:

Включать изображение на страницу с помощью include?! Даже не комментирую…
Спасибо за быстрый ответ, но Вы не поняли, я не изображение же вставляю include, а файл image.php, а в самом html коде, конечно же.

Мне не понятна вот эта часть Вашего кода:
// Отсылаем браузеру заголовок, сообщающий о том, что сейчас будет передаваться файл изображения
header(”Content-type: image/*”);

Это же получается второй header и выдается ошибка ( Если не сложно, пожалуйста, объясните? Я все сделала так, как Вы указали в коде, затем весь пхп в отдельном файле image.php я добавила в индексную страницу в то место, где планируется вывод картинки. (Пробовала и не отдельным файлом image.php делать, а втавлять код сразу в страницу, где оно выводится), но результат один и тот же:
Cannot modify header information — headers already sent by (output started at …
Заранее спасибо.

admin:

но Вы не поняли, я не изображение же вставляю include, а файл image.php, а в самом html коде, конечно же
Я прекрасно понял, что с помощью include вставляется файл image.php. И именно поэтому сказал “Даже не комментирую…”. Еще раз для особо сообразительных — файл index.html (или index.php), где надо вывести изображение:

// здесь какой-то код
?>

.

// здесь еще какой-то код
?>
Изображение:

1) Какой тип поля использовать и вообще как харнится там картинка, в виде набора байтов?

2) Вопрос, вытекающий из предыдущего, как сделать запрос на вставку и указать это jpg, png, gif и т.д.?