だるろぐ

2010-02-01

画像をDBに保存してmod_rewriteを利用していい感じに扱う

| 01:26 | 画像をDBに保存してmod_rewriteを利用していい感じに扱うを含むブックマーク

画像もDBに格納して管理する ?扱いがめんどうなLOB(ラージオブジェクト)は使わない方法も含め

これをやった。ここ見れば十分。


ソース一式

http://github.com/hirafoo/image_db

試す場合は

  • DBIx::Class とかを入れる。他適宜入れる
  • mysql用意する
  • image_db ってデータベース作る
  • config/create.sql を使ってテーブル作る
  • config/httpd/image_db_vhost.conf を自分の環境に合わせて編集してapache起動する
./script/file2db.pl images/hirafoo_normal.jpg
./script/file2db.pl images/hirafoo_hanten.jpg
./script/file2db.pl images/hirafoo_color.jpg

で。アクセスしたりファイル消したりログを見たりすれば、ファイル生成、mod_rewriteが動く様子が分かるかと。


本文

何をやっているのかというと

  • 画像もDBに保存したい
  • mysqlではblob型などを使えばバイナリがそのまま保存できる
  • imgタグのsrc要素にスクリプトを指定し、content-typeはimage/jpgとかにしてbodyで画像を返せばいい
  • スクリプトDBに問い合わせを行い、格納した画像をデコードして返せばいい
  • しかし毎回そんな事してたら死ねる
  • そこでapachemod_rewriteを活用し、
    1. 画像があれば画像をそのまま返す
    2. 画像が無かった場合のみ、スクリプトに画像を生成させ、裏でDBからHDDに画像を保存しつつ、表では画像をbodyに返してやる
    3. 次回以降のアクセスでは、画像が既にあるので、スクリプトを解さず画像を返せる

という。面白い。


ハマりどころ

RewriteCondによるファイル存在チェックで、バーチャルホストのディレクティブの中では !-f が効かない。知らなかった。

なので DOCUMENT_ROOT をくっつけてフルパスでチェックする。

    RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f

参考:mod_rewriteの質問です。「RewriteCond %{REQUEST_FILENAME} !-f.. - 人力検索はてな


どんな時に使うの

遊んでるだけなので何とも言えないのだけど。

例えば。

  • svn co htdocs/images したら死にたくなった
  • ls htdocs/images したらシェルが応答しなくなった

そんな環境で使うと嬉しくなるかもしれません。

小さいファイルが膨大にあるよりは、でかいファイルが1個あるだけの方が好きなので。

ブランチ切る度に使いもしないファイルがどばっと生まれるとか苦痛です。

普段はlibやviewだけcoして既存のと差し替えて使ってたりする。


あと今回は apache -> DB だったけど、間にsquid挟むとかで遊べる気もする。


小細工どころ

__PACKAGE__->resultset_attributes({
    alias => 'image',
    from  => [{image => 'image'}],
});
  • いちいちORMと同名メソッド作ってまでモデルクラス作るのが面倒です
package ImageDB::ResultSet::Image;
use base qw/DBIx::Class::ResultSet ImageDB::Model::Image/;
  • configファイルをフルパスで書くのも、デプロイ場所が変わるたびにファイルパス書き換えるのも嫌です
    my $dist = $INC{"ImageDB/Utils.pm"};
    my $file = dir($dist)->parent->parent->parent->subdir('config')->file('database.yaml');
    my $config = LoadFile($file);

デモ

http://imagedb.hirafoo.net/

mozilla系だと、キャッシュ消してもイマイチ様子が伝わらないようだ。

IEchromeだといい感じに見える。

負荷の様子見てそのうち落とします。


終わり。

そういえば前職でこれやろうとしたら残念な事情によりやらなかった記憶が。

トラックバック - http://d.hatena.ne.jp/hirafoo/20100201

事務用品 名刺 デザイン