Как хранить фотографии в БД
Можно в блобе хранить также, или base64encode текстом.
Хранить их стоит в виде другой таблицы:
Где image_id — INT , генерящийся уникальным для каждой картинки (в простейшем варианте — auto_increment ). Ну и сохранять картинки, соответственно, с именами вида
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.3.11.43304
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Как хранить изображения в MySQL с помощью BLOB
BLOB (или Binary Large Object, большой двоичный объект) – это тип данных MySQL, который позволяет хранить двоичные данные: изображения, мультимедиа и файлы PDF.
Хранить изображения (такие как фотографии и подписи) в базе данных MySQL вместе с другой информацией удобно в том случае, если вы разрабатываете приложения с сильной привязкой к БД (например, портал поиска работы, база данных студентов или финансовое приложение), и в этой БД изображения должны быть синхронизированы с другими данными.
И тогда на помощь приходит тип данных BLOB. Этот подход устраняет необходимость в создании отдельной файловой системы для хранения изображений, а также централизует базу данных, делая ее более портативной и надежной, поскольку данные изолированы от файловой системы. А еще это упрощает создание резервных копий, поскольку вы можете создать один дамп MySQL, содержащий все ваши данные.
Извлечение данных обрабатывается быстрее, а при создании новых записей вы можете быть уверены, что правила проверки данных и ссылочная целостность четко соблюдены (особенно при использовании транзакций MySQL).
В этом мануале мы расскажем о том, как использовать тип данных BLOB для хранения изображений с помощью PHP.
Требования
- Сервер Ubuntu 18.04, предварительно настроенный согласно этим инструкциям.
- Стек LAMP, установленный на вашем сервере. С установкой вам поможет этот мануал (раздел о виртуальных хостах можно пропустить, здесь мы не будем их использовать).
1: Создание базы данных
Давайте начнем с создания тестовой базы данных для этого проекта. Подключитесь к серверу по SSH, а затем выполните следующую команду, чтобы войти на сервер MySQL как пользователь root:
sudo mysql -u root -p
Введите root-пароль базы данных MySQL и нажмите Enter, чтобы продолжить.
После этого выполните следующую команду, чтобы создать базу данных. В этом руководстве мы назовем ее test_company:
CREATE DATABASE test_company;
После создания БД вы увидите следующее:
Query OK, 1 row affected (0.01 sec)
Теперь нам нужно создать на сервере MySQL учетную запись test_user; не забудьте заменить PASSWORD сложным паролем:
CREATE USER ‘test_user’@’localhost’ IDENTIFIED BY ‘PASSWORD’;
Вы получите следующий результат:
Query OK, 0 rows affected (0.01 sec)
Чтобы предоставить пользователю test_user полные права доступа к базе данных test_company, запустите команду:
GRANT ALL PRIVILEGES ON test_company.* TO ‘test_user’@’localhost’;
Вы должны получить следующий результат:
Query OK, 0 rows affected (0.01 sec)
В завершение нужно сбросить таблицы привилегий, чтобы MySQL перезагрузил права:
На экране должно появиться:
Query OK, 0 rows affected (0.01 sec)
Теперь, когда база данных test_company и пользователь test_user готовы, мы можем перейти к созданию таблицы. Предположим, нам нужна таблица products для хранения списка товаров. Позже мы попробуем вставить и извлечь данные из этой таблицы, чтобы понять, как работает BLOB в MySQL.
Выйдите из оболочки MySQL:
Затем снова войдите в систему, на этот раз – как пользователь test_user:
mysql -u test_user -p
При появлении запроса введите пароль test_user и нажмите Enter, чтобы продолжить. Затем откройте базу данных test_company, набрав команду:
Перейдя в базу данных test_company, MySQL отобразит такой результат:
Затем создайте таблицу products:
CREATE TABLE `products` (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE, product_image BLOB) ENGINE = InnoDB;
Эта команда создаст таблицу по имени products. В таблице будет четыре столбца:
- product_id: в этом столбце используется тип данных BIGINT, он позволяет вместить большой список продуктов, содержащий 2⁶³-1 элементов. Мы пометили столбец как PRIMARY KEY, чтобы присвоить товарам уникальные идентификаторы. Чтобы MySQL мог обрабатывать создание новых идентификаторов, мы использовали ключевое слово AUTO_INCREMENT.
- product_name: этот столбец содержит названия товаров. Здесь мы использовали тип данных VARCHAR, так как это поле обычно обрабатывает буквенно-цифровые значения длиной до 50 символов; ограничение в 50 символов – это всего лишь гипотетическое значение, используемое для целей этого руководства.
- price: этот столбец содержит розничные цены наших товаров. Поскольку цена на некоторые товары может выражаться числом с плавающей точкой (например, 23.69, 45.36, 102.99), мы указали здесь тип данных DOUBLE.
- product_image: в этом столбце мы указали тип данных BLOB, поскольку он предназначен для хранения двоичных данных – изображений товаров.
Для поддержки широкого спектра функций, включая транзакции MySQL, мы использовали механизм InnoDB. Выполнив вышеприведенную команду для создания таблицы, вы увидите следующий результат:
Query OK, 0 rows affected (0.03 sec)
Выйдите из сервера MySQL:
Вы получите сообщение:
Таблица products готова. Вы можете использовать ее для хранения некоторых записей, включая изображения продуктов. Скоро мы заполним ее данными.
2: Создание PHP-скрипта для заполнения базы данных
На этом этапе мы создадим сценарий PHP, который будет подключаться к базе данных MySQL, созданной в первом разделе руководства. Сценарий подготовит три записи о товарах и вставит их в таблицу products.
Чтобы создать PHP-скрипт, откройте новый файл в текстовом редакторе:
sudo nano /var/www/html/config.php
Затем вставьте в него следующую информацию (замените PASSWORD паролем test_user, который вы создали в разделе 1):
<?php
$pdo = new PDO(«mysql:host=» . DB_HOST . «; dbname https://i.imgur.com/VEIKbp0.png»)
‘product_name’ => ‘MANAGED KUBERNETES’,
‘product_name’ => ‘MySQL DATABASES’,
$sql = «INSERT INTO products(product_name, price, product_image) VALUES (:product_name, :price, :product_image)»;
foreach ($products as $product) <
echo «Records inserted successfully»;
Сохраните и закройте файл.
Этот файл нужен для определения переменных базы данных и подключения к ней. Файл также инициирует объект PDO и сохраняет его в переменной $pdo. Мы ссылаемся на файл config.php вверху.
Затем мы создали массив данных о товарах, которые нужно вставить в БД. Помимо product_name и price, которые заданы в виде строк и числовых значений соответственно, сценарий использует встроенную функцию PHP file_get_contents для чтения изображений из внешнего источника и передачи их в виде строк в столбец product_image.
После этого мы подготовили оператор SQL и использовали оператор PHP foreach <…>для вставки каждого продукта в базу данных.
Запустите /var/www/html/insert_products.php в окне браузера, используя следующий URL-адрес (не забудьте заменить your-server-IP внешним IP-адресом сервера):
На экране вы увидите сообщение об успешном выполнении файла – следовательно, записи были вставлены в базу данных.
Records inserted successfully
Итак, мы успешно вставили три записи, содержащие изображения товаров, в таблицу. На следующем этапе мы напишем сценарий PHP для извлечения этих записей и отображения их в браузере.
3: Извлечение и визуализация данных из БД MySQL
Имея в базе данных информацию и изображения товаров, вы можете написать второй сценарий PHP, который будет запрашивать и отображать данные в таблице HTML в браузере.
Чтобы создать файл, введите:
sudo nano /var/www/html/display_products.php
Затем вставьте в файл следующее:
<title>Using BLOB and MySQL</title>
<?php
$sql = «SELECT * FROM products»;
<table border = ‘1’ align = ‘center’> <caption>Products Database</caption>
<?php
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) <
‘<img src = «data:image/png;base64,’ . base64_encode($row[‘product_image’]) . ‘» width = «50px» height = «50px»/>’
Сохраните изменения в файле и закройте его.
Мы снова сослались на файл config.php для подключения к базе данных. Затем мы с помощью PDO создали и выполнили оператор SQL для извлечения всех элементов из таблицы; это делается при помощи команды SELECT * FROM products.
Затем мы создали таблицу HTML и заполнили ее данными о товарах с помощью PHP-оператора while() <…>. Строка $row = $stmt->fetch(PDO::FETCH_ASSOC) запрашивает БД и сохраняет результат в переменной $row в виде многомерного массива, который затем отображается в столбце таблицы HTML с помощью $row[‘column_name’].
Изображения из столбца product_image заключены в теги <img src = “”>. Мы задали атрибуты ширины и высоты, чтобы уменьшить размер изображений (иначе бы они не поместились в столбце таблицы HTML).
Чтобы преобразовать данные, содержащиеся в типе BLOB, обратно в изображения, мы использовали встроенную PHP функцию base64_encode и следующий синтаксис для схемы Data URI:
В этом случае image/png – это media_type, а строка в кодировке Base64 из столбца product_image – это base_64_encoded_data.
Запустите файл display_products.php в веб-браузере:
После запуска файла display_products.php вы увидите в браузере HTML-таблицу со списком товаров и их изображениями.
Это значит, что наш сценарий PHP правильно извлекает и визуализирует изображения и другие данные MySQL.
Заключение
В этом руководстве вы научились использовать тип данных BLOB для хранения и отображения картинок с помощью PHP. Вы также на практике увидели основные преимущества хранения изображений в базе данных (по сравнению с их хранением в файловой системе). Среди главных преимуществ: портативность, безопасность и простота резервного копирования. Если вы создаете приложение, которое требует, чтобы данные и связанные с ними изображения хранились вместе, то эта технология может быть очень вам полезна.
За дополнительной информацией о поддерживаемых типах данных в MySQL обращайтесь сюда. Если вам нужны дополнительные инструкции о связке MySQL и PHP, ознакомьтесь со следующими руководствами:
Хранение изображений сайта в БД
Автор должен признаться: статья родилась и выросла из довольно небольшой и не претендующей на откровение оптимизации сайта, описанного в другом материале. Сайт этот связан с музыкальной тематикой и, соответственно, активно отображает обложки альбомов, хранящиеся (до поры до времени) на сервере не в ФС , как обычно бывает, а в БД SQL Server (в BLOB-поле, о чём несложно догадаться); в старом варианте пора извлечения изображений из базы и сохранения их в виде файлов возникает в момент запроса альбомов пользователем, после чего (по истечении сессии) они удаляются.

Чтобы почти окончательно развеять куцую интригу и помочь возможному читателю определиться с тем, имеет ли смысл продолжить чтение, опишу конечный результат оптимизации: обложки по-прежнему останутся в базе данных, причём в поле того же типа, но вот веб-сервер, отдающий в итоге изображения клиенту, будет «обманут» и станет обращаться за файлом знать не зная, что его на самом деле нет в ФС, а вызов идёт сразу и непосредственно к СУБД. Такой «обман» конечно же не является самоцелью – всё в основном затевалось ради уменьшения нагрузки на дисковую подсистему.
Старая реализация
Прежде всего необходимо напомнить структуру HTML-тэга img , обязательным у которого является лишь атрибут src :
У несложных сайтов изображение, находящееся по URL в этом атрибуте, веб-сервер обычно напрямую извлекает из ФС, т. к. относительный путь к нему очень часто совпадает со структурой каталогов на сервере, а имя файла тоже берётся непосредственно из ФС; однако такое распространённое поведение, если брать конкретно IIS (именно он применяется в данном проекте), может быть заменено на совершенно другое за счёт модулей (расширений), когда изображения станут, к примеру, генерироваться на лету (т. е. физически они нигде не хранятся). Так вот статья затрагивает лишь первый вариант.
На этом сайте обложки располагаются не в файловой системе из-за желания «всё своё носить с собой» – чтобы резервная копия БД содержала полный набор информации, была самодостаточной; соответственно, дабы веб-сервер мог отдать изображение клиенту, оно, как уже говорилось, должно быть извлечено из базы данных и сохранено в виде файла, что добавляет лишнюю операцию: сначала читаем из БД, после чего записываем копию на диск, бездарно и теряя дисковое пространство, и нагружая эту подсистему. Ко всему прочему, если несколько разных пользователей относительно одновременно запросят одну и ту же обложку, то из-за того, что в uniGUI каждый из них представлен отдельной сессией, файл дополнительно продублируется ещё и для каждой из них.
Схематически и упрощённо описанное непотребство можно представить следующим образом:

Если проиллюстрировать прошлую реализацию кодом, то его логика будет иметь довольно классический вид:
- Запрос на выборку данных возвращает, среди прочих, и BLOB-поле с обложкой (в данном случае на примере компонента spAlbums типа TFDStoredProc из состава FireDAC).
- Изображение из поля, в зависимости от формата (png, jpg…), загружается в соответствующего наследника TGraphic.
- Далее используется предоставляемая uniGUI функция uniImageToURL , сохраняющая изображение в нужную папку и возвращающая готовый URL для атрибута src .
Идеальный вариант
Если предаться мечтаниям и представить, что обложки по-прежнему находятся в БД в BLOB-поле, а IIS каким-то образом, почти без усилий и программирования с нашей стороны, сам извлекает их, то окажется, что SQL Server способен такую мечту исполнить – за счёт функционала FileTable, представляющего собой, если очень кратко, создаваемую разработчиком специального вида таблицу, каждая запись которой отображается в файл в NTFS; обращение к таким файлам ничем не отличается от стандартного (однако некоторые возможности не поддерживаются), т. е. их можно просматривать, изменять и удалять хоть через Проводник.
Если снова графически показать такую схему, то мы избавимся от копирования обложки в папку сайта:

Данный вариант полностью совместим и с отложенной загрузкой изображений, настраиваемой скажем через атрибут loading , т. е. если пользователь не прокрутит страницу сайта до некоторых обложек, то они и не будут прочитаны из базы (написанное, разумеется, справедливо и для случая, когда в браузере вообще отключен показ изображений):
Чтобы воспользоваться этой манной небесной, ниспосланной SQL Server, потребуется, само-собой, выполнить некоторые действия как на стороне СУБД, так и на стороне IIS, чему собственно и посвящена оставшаяся практическая часть статьи. Но предварительно хотелось бы сделать небольшую ремарку и отметить, что конкуренты Microsoft тоже могут предложить тонкую работу с BLOB, но функционал уровня FileTable автору удалось найти лишь у Oracle – речь о Database File System (DBFS). Остальные же игроки предоставляют лишь условно традиционный (но неизбежно СУБД-специфичный) API, несколько примеров:
Настройка SQL Server
По умолчанию FileTable-возможности отключены в SQL Server. Официальная документация содержит весьма подробную и внятную инструкцию по параметрам, которые необходимо задействовать как на уровне всего экземпляра, так и в конкретной базе данных, отчего не представляется разумным пересказывать здесь подобные тонкости – вместо этого автор сосредоточится на небольшом SQL-скрипте, выполняющем перенос обложек из существующей таблицы с альбомами в новую FileTable-таблицу (если же в Вашем случае файлы изначально в БД не хранятся, в отличие от данного проекта, то с их адаптацией к FileTable поможет документация).
Таблицы
Далее в скрипте предполагается следующая структура двух только что упомянутых таблиц (источника – с данными об альбомах, и приёмника – новой таблицы с обложками):
| Поле | Тип данных | Описание |
|---|---|---|
| ID | integer | Первичный ключ. |
| Cover | varbinary(max) | BLOB-поле с собственно изображением, которое нужно перенести в новую таблицу. |
| CoverFormat | nvarchar(10) | Тип изображения (jpg, png и т. д.). |
| Прочие поля (название альбома, год издания и т. п.). |
| Поле | Тип данных | Описание |
|---|---|---|
| path_locator | hierarchyid | Первичный ключ. |
| file_stream | varbinary(max) | Содержимое файла (в нашем случае это изображение). |
| name | nvarchar(255) | Название файла (с расширением), отображаемое в ФС. |
| Прочие поля. |
| Поле | Тип данных | Описание |
|---|---|---|
| CoverID | hierarchyid | Внешний ключ на приёмник. |
| Прочие поля. |
Скрипт
Все действия с базой логически делятся на несколько этапов:
-
Банальнейшее по реализации добавление поля CoverID в источник:
Использование MERGE вместо конструкции INSERT продиктовано невозможностью в последней обратиться в блоке OUTPUT к полям любых задействованных таблиц (допустимы только поля той, в которую и происходит вставка). Другими словами, было бы нечем заполнить поле AlbumID табличной переменной @Covers , т. к. обращение ниже выполняется к таблице-источнику, а вставка идёт в dbo.AlbumCover :
Оговорка про «почти» связана с тем, что читатель может столкнуться с отсутствием доступа при попытке обратиться к означенным файлам – в этом случае следует ознакомиться с той частью следующего раздела, где описывается нюанс с правами. Также для определённости примем, что наш путь выглядит как \\ServerName\MSSQLSERVER\DatabaseName\AlbumCover (далее в другом примере будет отсылка к нему, где для наглядности потребуется конкретное значение).
Настройка веб-сервера
Хотя в текущем разделе демонстрация идёт на примере IIS, но большинство вещей применимы и к любому другому веб-серверу, ибо являются скорее ОС- и СУБД-специфичными.
Права на чтение
Если снова вернуться к атрибуту src тэга img , то становится очевидной небольшая проблема: путь в атрибуте должен быть относительным, а нужные изображения доступны лишь по UNC-пути. Решение довольно просто́ и заключается в создании символической ссылки в папке сайта; если условиться, что физически сайт располагается в каталоге c:\IIS\SiteName, а ссылка будет называться Covers, то её добавление выполняется следующей командой в консоли:
Теперь атрибут src станет возможно заполнять подобным образом:
Доработки Delphi-кода, дающие показанное значение для src , будут приведены в конце статьи, а пока же остался важный нюанс с правами (в нашем случае достаточно лишь на чтение), причём делящийся на две части:
-
Предоставление доступа (на уровне ФС) пользователю IUSR и группе IIS_IUSRS для созданной символической ссылки:

-
Логин создаётся на основе Windows-пользователя вида IIS APPPOOL\<Имя нужного пула>.
Проверка подлинности
Последнее, что требуется настроить, относится непосредственно к IIS, а именно к проверке подлинности на сайте – чтобы она выполнялась от имени пула приложений, чуть выше только что получившего права на чтение обложек (если в сценарии читателя проверка обязана проходить от иного пользователя, то данный раздел можно пропустить, но при этом необходимо добавить ещё одну пару «логин-пользователь» как описано в предыдущем разделе, связав имя входа со значением из параметров проверки подлинности).
Использование типа данных MySQL BLOB для хранения изображений с PHP в Ubuntu 18.04

Большие двоичные объекты ( BLOB ) — это тип данных MySQL для хранения двоичных данных, таких как изображения, мультимедийные файлы и файлы PDF.
При создании приложений, для которых требуются тесно связанные базы данных, где изображения нужно синхронизировать с другими данными (например, портал сотрудников, база данных студентов или финансовое приложение), будет полезно хранить изображения, например, фотографии паспортов и подписей студентов, в базе данных MySQL вместе с другой связанной информацией.
Для этой цели будет полезен тип данных MySQL BLOB . Такой подход к программированию устраняет необходимость создания отдельной файловой системы для хранения изображений. Такая схема также обеспечивает централизацию базы данных, делая ее более портативной и безопасной за счет изоляции данных от файловой системы. Создавать резервные копии также будет проще, поскольку для этого достаточно будет создать один файл дампа MySQL, где будут храниться все ваши данные.
В этом обучающем модуле мы используем тип данных MySQL BLOB для сохранения изображений в коде PHP в Ubuntu 18.04.
Предварительные требования
Для выполнения этого обучающего модуля вам потребуется следующее:
- Сервер Ubuntu 18.04, настроенный в соответствии с указаниями руководства Начальная настройка сервера Ubuntu 18.04 и пользователь без прав root с привилегиями sudo .
- Apache, MySQL и PHP, установленные в соответствии с указаниями руководства «Установка комплекта Linux, Apache, MySQL, PHP (LAMP) в Ubuntu 18.04». Для этого обучающего модуля необязательно создавать виртуальные хосты, поэтому вы можете пропустить шаг 4.
Шаг 1 — Создание базы данных
Для начала создайте тестовую базу данных для своего проекта. Для этого подключитесь к серверу через SSH и запустите следующую команду для входа на сервер MySQL с привилегиями root:
Введите пароль пользователя root для вашей базы данных MySQL и нажмите ENTER , чтобы продолжить.
Затем запустите следующую команду для создания базы данных. В этом обучающем модуле мы назовем базу данных test_company :
После создания базы данных вы увидите следующее:
Затем создайте учетную запись test_user на сервере MySQL и обязательно замените PASSWORD на надежный пароль:
Вывод должен выглядеть так:
Чтобы предоставить пользователю test_user полные права доступа к базе данных test_company , выполните команду:
Вы должны увидеть следующее:
Очистите таблицу прав доступа, чтобы СУБД MySQL перезагрузила разрешения:
На экран должно быть выведено следующее:
Мы подготовили базу данных test_company и пользователя test_user . Теперь мы можем перейти к созданию таблицы products для сохранения образцов продуктов. Позднее мы используем эту таблицу для вставки и получения записей, чтобы продемонстрировать работу объектов MySQL BLOB .
Выполните выход из сервера MySQL:
Снова войдите в систему под учетными данными созданного пользователя test_user :
Введите в диалоге пароль пользователя test_user и нажмите ENTER , чтобы продолжить. Переключитесь на базу данных test_company с помощью следующей команды:
После выбора базы данных test_company MySQL выведет на экран следующее:
Затем создайте таблицу products , запустив команду:
Эта команда создает таблицу с именем products . В таблице имеется четыре столбца:
product_id : в этом столбце используется тип данных BIGINT , за счет чего обеспечивается поддержка больших списков продуктов, где может содержаться до 2⁶³-1 элементов. Вы пометили столбец как PRIMARY KEY для уникальной идентификации продуктов. Чтобы MySQL обрабатывала генерирование новых идентификаторов для вставленных столбцов, вы использовали ключевое слово AUTO_INCREMENT .
product_name : в этом столбце хранятся названия продуктов. Мы использовали тип данных VARCHAR , поскольку это поле обычно обрабатывает не более 50 бувенно-числовых символов. Предел в 50 символов — это гипотетическое значение, используемое для целей этого обучающего модуля.
price : для демонстрационных целей мы добавили в таблицу products столбец price для хранения информации о розничной цене продуктов. Поскольку некоторые продукты могут иметь значения с плавающей запятой (например, 23.69, 45.36, 102.99), мы использовали тип данных DOUBLE .
product_image : в этом столбце данные типа BLOB используются для хранения двоичных данных изображений продуктов.
Мы использовали для таблицы InnoDB , СИСТЕМУ ХРАНЕНИЯ , поддерживающую широкий набор функций, включая транзакции MySQL. После выполнения этой команды для создания таблицы products вы увидите на экране следующее:
Выполните выход с сервера MySQL:
Вы увидите следующее
Теперь таблица products готова для хранения записей, в том числе изображений продуктов, и на следующем шаге мы заполним ее продуктами.
Шаг 2 — Создание скриптов PHP для подключения к базе данных и ее заполнения
На этом шаге мы создадим скрипт PHP для подключения к базе данных MySQL, созданной нами на шаге 1. Этот скрипт подготовит три образца продуктов и вставит их в таблицу products .
Для создания кода PHP откройте новый файл в текстовом редакторе:
Введите в файл следующую информацию и замените PASSWORD паролем пользователя test_user , созданным на шаге 1:
Сохраните и закройте файл.
В этом файле мы использовали четыре константы PHP для подключения к базе данных MySQL, созданной на шаге 1:
DB_NAME : эта константа хранит название базы данных test_company .
DB_USER : эта переменная хранит имя пользователя test_user .
DB_PASSWORD : эта константа хранит ПАРОЛЬ MySQL для учетной записи test_user .
DB_HOST : сервер, где располагается база данных. В данном случае мы используем сервер localhost .
Следующая строка в вашем файле инициирует объект данных PHP (PDO) и выполняет подключение к базе данных MySQL:
Ближе к концу файла мы зададим пару атрибутов PDO:
- ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION : этот атрибут предписывает PDO выдать исключение, которое можно зарегистрировать для целей отладки.
- ATTR_EMULATE_PREPARES, false : эта опция повышает безопасности, предписывая СУБД MySQL выполнять подготовку вместо PDO.
Мы добавим файл /var/www/html/config.php в два скрипта PHP для вставки и получения записей, которые мы сейчас создадим.
Вначале создайте скрипт PHP /var/www/html/insert_products.php для вставки записей в таблицу products:
Затем добавьте следующую информацию в файл /var/www/html/insert_products.php :
Сохраните и закройте файл.
Вы добавили файл config.php в верхней части файла. Это первый файл, который вы создали для определения переменных базы данных и подключения к базе данных. Также этот файл инициирует объект PDO и сохраняет его в переменной $pdo .
Далее вы создали массив данных о продуктах, которые нужно вставить в базу данных. Помимо значений product_name и price , подготовленных в виде текстовых и числовых значений соответственно, данный скрипт использует встроенную функцию PHP file_get_contents для чтения изображений из внешнего источника и передачи их в виде строк в столбец product_image .
Затем вы подготовили выражение SQL и использовали выражение PHP foreach <. >для вставки каждого продукта в базу данных.
Для выполнения файла /var/www/html/insert_products.php запустите его в окне браузера, используя следующий URL. Замените your-server-IP публичным IP-адресом вашего сервера:
После выполнения файла вы получите в браузере сообщение, подтверждающее успешную вставку записей в базу данных.

Вы успешно вставили три записи с изображениями продуктов в таблицу products . На следующем шаге мы создадим скрипт PHP для извлечения этих записей и их вывода в браузере.
Шаг 3 — Отображение информации о продуктах из базы данных MySQL
Мы разместили в базе данных информацию о продуктах и их ихображения. Теперь мы создадим еще один скрипт PHP, который будет запрашивать и выводить информацию о продуктах в таблице HTML в браузере.
Для создания файла введите следующее:
Затем введите в файл следующую информацию:
Сохраните изменения в файле и закройте его.
Здесь мы опять использовали файл config.php для подключения к базе данных. Затем мы подготовили и выполнили команду SQL, используя PDO для извлечения всех элементов из таблицы products с помощью команды SELECT * FROM products .
Затем мы создали таблицу HTML и заполнили ее данными о продуктах, используя выражение PHP while() <. >. Строка $row = $stmt->fetch(PDO::FETCH_ASSOC) отправляет запрос в базу данных и сохраняет результат в переменной $row как многомерный массив, который затем отображается как столбец таблицы HTML с использованием синтаксиса $row[‘column_name’] .
Изображения из столбца product_image заключены в теги <img src = ""> . Мы использовали атрибуты width и height для уменьшения ширины и высоты изображений, чтобы они поместились в столбце таблицы HTML.
Чтобы конвертировать данные, хранящиеся в объекте типа BLOB , обратно в изображения, мы использовали встроенную функцию PHP base64_encode и следующий синтаксис схемы URI данных:
В данном случае image/png — это значение параметра media_type (тип файла), а закодированная строка Base64 из столбца product_image — это данные base_64_encoded_data .
Выполните в браузере файл display_products.php , введя следующий адрес:
Запустив в браузере файл display_products.php , вы увидите таблицу HTML со списком продуктов и связанных с ними изображений.

Это подтверждает, что скрипт PHP для извлечения изображений из базы данных MySQL работает ожидаемым образом.
Заключение
В этом обучающем модуле мы использовали тип данных MySQL BLOB для хранения и вывода изображений в коде PHP в Ubuntu 18.04. Мы увидели основные преимущества хранения изображений в базе данных по сравнению с их хранением в файловой системе. В число этих преимуществ входят портативность, безопасность и удобство резервного копирования. Эта технология будет вам полезна, если вы создаете приложение, для которого требуется хранить информацию и изображения вместе, например, студенческий портал или базу данных сотрудников.
Дополнительную информацию о поддерживаемых типах данных в MySQL можно найти в руководстве по типам данных MySQL. Если вас интересуют дополнительные материалы по MySQL и PHP, пройдите следующие обучающие модули:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.