この記事は2年以上前に書かれたものです。
情報が古い可能性があります。
情報が古い可能性があります。
検証バージョンはPostgreSQLが9.2、PHPが5.4.7です。PDOは今回使用していません。
注意:
bytea 型を SELECT した場合、PostgreSQL は ‘\’ で 始まる 8 進数のバイト値(例: \032)を返します。これをユーザーが手動で コンバートすることを期待されています。
とかPHP Manualに書いてるんですけどそもそもPHP Manualに書いてある例がちゃんと動いてくれなかったのでENCODEでコンバートしましたよ(‘A`)
PHP: pg_unescape_bytea – Manual
フォルダ構成はこんな感じ。

テーブルの作成
CREATE TABLE image ( byte_data bytea, id serial NOT NULL, CONSTRAINT id PRIMARY KEY (id) );
ソース
image.php
<?php
/**
* UTF-8 BOM なしで保存しています。
*
* <img src="image.php?id=画像ID" />
* という形で画像出力を行う
*/
//イメージIDを取得
if( !isset( $_GET['id'] ) ) exit;
$id = $_GET['id'];
//数値チェック
if( !is_numeric( $id ) ) exit;
else $id = intval( $id );
//DB接続
$conn = pg_connect( 'host=localhost port=5432 dbname=sample user=postgres password=passwd' );
if( $conn == false ) exit;
//bytea 型を SELECT した場合、PostgreSQL は '\' で 始まる 8 進数のバイト値(例: \032)を返します。これをユーザーが手動で コンバートすることを期待されています。
// bytea データを取得する(ENCODEでコンバート)
$sql = "SELECT ENCODE( byte_data::bytea, 'escape' ) byte_data FROM image WHERE id= {$id} ";
$res = pg_query( $sql );
if( $res == false ) exit;
//クエリ結果をオブジェクトして取得
$data = pg_fetch_object( $res );
if( $data == false ) exit;
//クエリ 結果 resource に関するメモリとデータを開放
pg_free_result( $res );
//DB切断
pg_close( $conn );
//画像の情報を取得する(※要GDライブラリ有効)
$img = base64_encode( pg_unescape_bytea( $data->byte_data ) );
$scheme = 'data:application/octet-stream;base64,';
$size = getimagesize( $scheme . $img );
if( $size == false ) exit;
//バイナリに変換し、ブラウザに送信する
header( 'Content-type: ' . $size['mime'] );
echo pg_unescape_bytea( $data->byte_data );
exit;
index.php
<?php
/**
* UTF-8 BOM なしで保存しています。
*/
//Smartyのlibフォルダがinclude_pathに入っていること
require_once( 'Smarty.class.php' );
//Smarty初期設定
$smarty = new Smarty();
//PHP5.3.0以上では dirname( __FILE__ ) => __DIR__ でも可能
$smarty->template_dir = dirname( __FILE__ ) . '/';
$smarty->compile_dir = dirname( __FILE__ ) . '/compile/';
$smarty->config_dir = dirname( __FILE__ ) . '/configs/';
//DBへの接続を行う
$conn = pg_connect( 'host=localhost port=5432 dbname=sample user=postgres password=passwd' );
//取り敢えずのデータ生成
$images = array( 'img/cat.jpg', 'img/php.gif', 'img/children.png' );
for( $i =0; $i < count( $images ); $i++ ) {
//バイナリファイルを読み込む
$data = file_get_contents( $images[ $i ] );
//バイナリデータをエスケープする
$esc = pg_escape_bytea( $data );
//DBに登録
pg_query( "INSERT INTO image (byte_data) VALUES ('{$esc}')" );
}
//テンプレートを表示する
$smarty->assign( 'msg', '画像出力テスト' );
$smarty->display( 'index.tpl' );
index.tpl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{$msg}</title>
<meta name="viewport" content="width=device-width" />
<meta name="description" content="" />
<meta name="keywords" content="" />
</head>
<body>
<h1>{$msg}</h1>
<img src="image.php?id=1" alt="猫" />
<img src="image.php?id=2" alt="PHP" />
<img src="image.php?id=3" alt="子供" />
</body>
</html>
実行例
