#php #mysql #blob
#php #mysql #большой двоичный объект
Вопрос:
Как бы я отображал данные большого двоичного объекта с помощью PHP? Я ввел большой двоичный объект в базу данных, но как мне его извлечь? Любые примеры были бы великолепны.
Комментарии:
1. извините, под большим двоичным объектом я имел в виду картинку
Ответ №1:
Я рассматривал возможность голосования за закрытие этого дубликата, но название довольно хорошее, и, просматривая другие вопросы, я не нахожу полного ответа на общий вопрос. Такого рода вопросы выдают отсутствие понимания основ HTTP, поэтому вместо этого я написал этот длинный ответ. Я немного умолчал, но любому, кто понимает следующее, вероятно, не нужно было бы задавать подобный вопрос. Или, если бы они это сделали, они могли бы задать более конкретный вопрос.
Первое — Если вы храните изображения или другие файлы в базе данных, остановитесь и пересмотрите свою архитектуру. СУБД на самом деле не оптимизированы для обработки больших двоичных объектов. Существует ряд (нереляционных) баз данных, которые специально настроены для обработки файлов. Они называются файловыми системами, и они действительно хороши в этом. По крайней мере, в 95% случаев, когда я обнаруживал, что обычные файлы застряли в RDBMS, это было бессмысленно. Итак, прежде всего, подумайте о том, чтобы не хранить данные файла в базе данных, используйте файловую систему и храните некоторые небольшие данные в базе данных (пути, если необходимо, часто вы можете организовать свою файловую систему так, чтобы все, что вам нужно, это уникальный идентификатор).
Итак, вы уверены, что хотите сохранить свой большой двоичный объект в базе данных?
В таком случае вам нужно понимать, как работает HTTP. Не вдаваясь в подробности, всякий раз, когда какой-либо клиент запрашивает URL (делает HTTP-запрос), сервер отвечает HTTP-ответом. HTTP-ответ состоит из двух основных частей: заголовков и данных. Две части разделены двумя последовательными символами новой строки.
Заголовки на проводе представляют собой простые текстовые пары ключ / значение, которые выглядят как:
Name: value
и разделяются новой строкой.
Данные в основном представляют собой большой двоичный объект. Это просто данные. Способ интерпретации данных определяется (клиентом) на основе значения заголовка Content-Type, который сопровождает его. Заголовок Content-Type указывает тип интернет-носителя данных, содержащихся в разделе data.
Посмотрите, как это работает
В этом нет ничего волшебного. Для обычной HTML-страницы весь ответ доступен для чтения человеком. Попробуйте следующее:
$ telnet google.com 80 # connect go google.com on port 80
Вы увидите что-то вроде:
Trying 74.125.113.104...
Connected to google.com.
Escape character is '^]'.
Теперь введите:
GET /
(с последующим возвратом).
Вы только что сделали очень простой HTTP-запрос! И вы, вероятно, получили ответ. Посмотрите на ответ. Вы увидите все заголовки, за которыми следует пустая строка, за которой следует HTML-код домашней страницы Google.
Ну и что?
Итак, теперь вы знаете, что делают веб-серверы. Они принимают запросы (например GET /
) и возвращают ответы (состоящие из заголовков, за которыми следует пустая строка (два последовательных перевода строки), за которыми следуют данные).
Теперь пришло время осознать, что:
Ваше веб-приложение на самом деле просто настроенный веб-сервер
Весь тот код, который вы пишете, принимает любой запрос и преобразует его в HTTP-ответ. Итак, вы в основном просто создаете специализированную версию apache, или IIS, или nginx, или lighty, или что угодно.
Теперь, способ по умолчанию, которым веб-сервер обычно обрабатывает запросы, заключается в поиске файла в каталоге (корень документа), просмотре его, чтобы выяснить, какие заголовки отправлять, а затем отправке этих заголовков, за которыми следует содержимое файла.
Но, в то время как ваш веб-сервер делает все это волшебным образом для файлов в файловой системе, он совершенно не осведомлен о некоторых больших двоичных объектах в СУБД. Так что вам придется сделать это самостоятельно.
Если вы знаете, что содержимое вашего большого двоичного объекта — это, скажем, изображение в формате JPG, которому следует присвоить имя на основе столбца «name» в той же таблице, вы могли бы сделать что-то вроде:
<?php
$result = query('select name, blobdata from table where id = 5');
$row = fetch_assoc($result);
header('Content-Type: image/jpeg');
echo $row['blobdata'];
?>
(Если вы хотите намекнуть, что браузер должен загрузить файл вместо его отображения, вы могли бы использовать дополнительный заголовок, такой как: header('Content-Disposition: attachment; filename="' . $row['name'].'"');
)
PHP достаточно умен, чтобы предоставить функцию header (), которая устанавливает заголовки и гарантирует, что они отправляются первыми (и отделяются от данных). Как только вы закончите настройку заголовков, вы просто отправляете свои данные.
Пока ваши заголовки предоставляют клиенту достаточно информации о том, как обрабатывать полезную нагрузку данных, все идет как по маслу.
Ура.
Ответ №2:
Простой пример:
$blob_data = "something you've got from BLOB field";
header('Content-type: image/jpeg'); // e.g. if it's JPEG image
echo $blob_data;