LUNARAVE WEBクリエイターの仕事と休息

アクセスカウンタ

Google Maps APIの利用戦国IXAWeb技術Youtubeチャンネル

zoom RSS 画像をデータベースに格納する -PostgreSQL-

<<   作成日時 : 2010/02/24 22:44   >>

なるほど(納得、参考になった、ヘー) ブログ気持玉 4 / トラックバック 0 / コメント 0

ECサイトやCMSなどコンテンツをブラウザから作成する場合、画像もアップロードすることは避けては通れない道だが、アップロードした画像をそのままサーバに保存するのではなく、データベースに格納することで得られるメリットもある。

サーバ側で画像などのファイルを受け取るにはPerlやPHPといったCGIで実装することができ、多くの場合は受け取った画像をそのままサーバに保存しているだろう。

作り手側としてもその方が楽なので良いが、顧客や扱う画像によってはセキュリティを高める目的でデータベースに格納することを要求されることがある。


【画像をそのままサーバに保存することの特徴】
・プログラムが比較的簡単
・保存された画像を呼び出す場合にファイルパスを指定するだけで簡単
・保存された画像を表示させるにはWebサーバの公開ディレクトリに置く必要がありセキュリティに問題有り
・バックアップする場合に画像フォルダも指定しなければならず手間

【画像をデータベースに保存することの特徴】
・CGIの他にデータベースが必要である程度のサーバが要求される
・プログラムが複雑
・画像がサーバの公開ディレクトリに無いのでセキュリティを高められる
・バックアップはデータベースのダンプだけで簡単


以上のように、画像をデータベースに格納する特徴としては「手間がかかるがセキュリティが高く、バックアップが簡単」なことが挙げられる。

では、実際にデータベースに格納して表示させるプログラムを用意する。

今回はCGIは"PHP"とし、データベースは"postgreSQL"を利用する。


まず、データベースにテーブルを用意するのだが、この時に画像を入れるカラムの型に"bytea"を設定する。
"postgreSQL"をブラウザから操作する"phpPgAdmin"からでも生成することができる。

 カラム設定


次に画像をデータベースに格納するプログラムは下記のようにする。
画像のパスとファイル名は固定にしたが、実際はPOSTで送信されてきた画像を受け取るように$img_dataを書き換える必要がある。


$img_data = '01.jpg';

$fp = fopen($img_data, "r");
$data = fread($fp,filesize($img_data));
fclose($fp);

$escaped = pg_escape_bytea($data);

$conn = "host=" . SERVER . " port=5432 dbname=" . NAME . " user=" . USER . " password=" . PASS;
$dbconn = pg_connect($conn);
$sql = "INSERT INTO テーブル (id, image) VALUES (" . $id . ", '" . $escaped . "')";
$res = pg_query($dbconn, $sql);
pg_close($dbconn);



重要ポイントは画像ファイルをオープンして、それを"pg_escape_bytea"でエスケープする点だ。
これが無いとデータベースには格納されるが、\マークが多く入ってしまい、画像を表示する際に表示されなくなる。

ちなみに、$connはデータベースに接続する処理で、$sqlは変数名の通りインサートするSQLを生成している。

未定義な変数名があるが、この辺りは利用する環境に合わせて置き換えれば使えるはず。


このソースを仮に"image.php"というファイル名にし、同階層に"01.jpg"を設置してブラウザやサーバのコマンドラインで実行するとデータベースに格納される。

 データベースに格納


では、データベースに入った画像を表示させるソースを次のように用意する。


$conn = "host=" . SERVER . " port=5432 dbname=" . NAME . " user=" . USER . " password=" . PASS;
$dbconn = pg_connect($conn);
$sql = "SELECT image FROM テーブル WHERE id = " . $id;
$res = pg_query($dbconn, $sql);
pg_close($dbconn);

$img_data = pg_fetch_result($res, 0, "image");
header('Content-Type: image/jpeg');
$img_data = pg_unescape_bytea($img_data);
print"${img_data}";



1行目から5行目まではデータベースに格納するときと同じで、データベースへ接続してSQLを実行している。

今回のSQLはSELECT文でデータを参照している。

その次からの処理が特殊で、まずは"header"で画像タイプを宣言している。

そしてデータベースから取得した画像を"pg_unescape_bytea"でアンエスケープして表示している。

このソースを"view.php"というファイル名にし、ブラウザでアクセスすると画像が表示される。


ただ、"header"のタイプが通常コンテンツと違い画像タイプなので、画像と一緒にHTMLなど文字も表示させることができない。

そのため、コンテンツの中にデータベースに格納した画像を表示させたい場合は<img src="view.php">というように"img"タグだけども、指定するパスを画像を呼び出すPHPを指定することで利用することができる。


実装するには複雑で手間がかかるが、前述したようにデータのバックアップは一元化できて非常に便利だし、直リンクで画像を指定されたく無い場合にも利用できるので取り入れてみてはいかがか。

テーマ

注目テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ
気持玉数 : 4
なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー)

トラックバック(0件)

タイトル (本文) ブログ名/日時

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
画像をデータベースに格納する -PostgreSQL- LUNARAVE WEBクリエイターの仕事と休息/BIGLOBEウェブリブログ
文字サイズ:       閉じる