Большие объекты (LOBs) в PHP PDO

PHP PDO 参考手册Справочное руководство по PHP PDO

В какой-то момент приложениям может понадобиться хранить «большие» данные в базе данных.

«Большие» обычно означает «примерно 4kb или больше», хотя некоторые базы данных могут легко обрабатывать до 32kb данных, прежде чем они станут «большими». Большие объекты по сути являются текстовыми или бинарными.

Использование кода типа PDO::PARAM_LOB в вызовах PDOStatement::bindParam() или PDOStatement::bindColumn() позволяет PDO использовать тип больших данных.

PDO::PARAM_LOB указывает PDO сопоставлять данные как поток, чтобы с ними можно было работать с помощью PHP Streams API.

Отображение изображения из базы данных

В следующем примере LOB привязывается к переменной $lob, затем с помощью fpassthru() он отправляется в браузер. Поскольку LOB представляет собой поток, к нему можно применять такие функции, как fgets(), fread() и stream_get_contents().

<?php
$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2');
$stmt = $db->prepare("select contenttype, imagedata from images where id=?");
$stmt->execute(array($_GET['id']));
$stmt->bindColumn(1, $type, PDO::PARAM_STR, 256);
$stmt->bindColumn(2, $lob, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);

header("Content-Type: $type");
fpassthru($lob);
?>

Вставка изображения в базу данных

В следующем примере открывается файл, и его дескриптор передаётся в PDO, чтобы вставить его как LOB. PDO заставляет базу данных извлекать содержимое файла наиболее эффективным способом.

<?php
$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2');
$stmt = $db->prepare("insert into images (id, contenttype, imagedata) values (?, ?, ?)");
$id = get_new_id(); // 调用某个函数来分配一个新 ID

// 假设处理一个文件上传
// 可以在 PHP 文档中找到更多的信息

$fp = fopen($_FILES['file']['tmp_name'], 'rb');

$stmt->bindParam(1, $id);
$stmt->bindParam(2, $_FILES['file']['type']);
$stmt->bindParam(3, $fp, PDO::PARAM_LOB);

$db->beginTransaction();
$stmt->execute();
$db->commit();
?>

Вставка изображения в базу данных: Oracle

При вставке LOB из файла Oracle немного отличается. Вставка должна выполняться после начала транзакции; в противном случае, когда запрос выполняется, только что вставленный LOB будет неявно зафиксирован с длиной 0:

<?php
$db = new PDO('oci:', 'scott', 'tiger');
$stmt = $db->prepare("insert into images (id, contenttype, imagedata) " .
"VALUES (?, ?, EMPTY_BLOB()) RETURNING imagedata INTO ?");
$id = get_new_id(); // 调用某个函数来分配一个新 ID

// 假设处理一个文件上传
// 可以在 PHP 文档中找到更多的信息

$fp = fopen($_FILES['file']['tmp_name'], 'rb');

$stmt->bindParam(1, $id);
$stmt->bindParam(2, $_FILES['file']['type']);
$stmt->bindParam(3, $fp, PDO::PARAM_LOB);

$stmt->beginTransaction();
$stmt->execute();
$stmt->commit();
?>

PHP PDO 参考手册Справочное руководство по PHP PDO

Другие расширения