アプリケーション内で、データベースに「大きな」データを格納する
必要を感じることがあるかもしれません。「大きな」とは、一般的には
「4kb 程度以上」を指しますが、データベースによっては 32kb くらいまでは
「大きい」と判断されずにすむこともあります。ラージオブジェクトは
テキストあるいはバイナリの両方の形式をとり得ます。
PDO でこのラージデータ型を扱うには、
PDOStatement::bindParam() や
PDOStatement::bindColumn() のコール時に
型コードとして PDO::PARAM_LOB
を使用します。
PDO::PARAM_LOB
を指定すると、PDO は
データをストリームにマップします。これにより、
PHP ストリーム API
を使用してデータを扱えるようになります。
例1 データベース内の画像を表示する
この例では $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);
?>
例2 画像をデータベースに挿入する
この例では、ファイルをオープンしてそのハンドルを 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();
?>
例3 画像をデータベースに挿入する: Oracle
Oracle は、ファイルから LOB を挿入する方法が他とは少し違います。 また、必ずトランザクション内で挿入しなければなりません。 それ以外の場合、新しく挿入された LOB は長さゼロとなり、クエリの 実行時に暗黙的にコミットされます。
<?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);
$db->beginTransaction();
$stmt->execute();
$db->commit();
?>