CakePHP3でDBに格納した画像データを表示してみた。
2017/09/04 追記
すっかり書いた気でいた画像データ登録記事を追加しました。
本記事と合わせて読んで頂くと、それっぽくできると思います。
画像データはDBにブチ込むタイプです。
サーバにアップロードする方法もありますが、どちらもメリット、デメリットあります。
メリット、デメリットに関してはグーグル先生が詳しいと思います。
案件に応じて柔軟に対応すればいいんじゃないかなと。
さて、いきなり端折ってしまいますが、image_filesというテーブルに画像データが入っていたとします。
いわゆるBLOB型のカラムですね。
テーブル構成はこんな感じで作りました。
CREATE TABLE `image_files` ( `id` int(11) NOT NULL AUTO_INCREMENT, `content_type` varchar(64) NOT NULL COMMENT 'コンテンツタイプ', `image_data` mediumblob NOT NULL COMMENT '画像バイナリデータ', `created` datetime DEFAULT NULL COMMENT 'データ作成日', `modified` datetime DEFAULT NULL COMMENT 'データ更新日', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='画像格納テーブル'
ここにブチ込んだ画像バイナリデータをController経由で表示します。
Helperでもいいと思いますが、あんまりHelperを使うのが好きではないのでControllerで。
やりたいことはこれだけです。
・プライマリキーであるimage_files.idを指定する。
・image_files.idに合致するバイナリデータのimage_files.image_dataを取得する。
・画面上に表示する。
なんか簡単っぽいです。
というわけで表示用のControllerを書いてみます。
<?php namespace App\Controller; use Cake\Event\Event; use Cake\ORM\TableRegistry; /** * ImageFilesController */ class ImageFilesController extends AppController { public $name = 'ImageFiles'; public function beforeFilter(Event $event) { parent::beforeFilter($event); } /** * 画像データ取得処理 * IDに合致する画像データを取得して表示 * @param type $imageId * @throws NotFoundException */ public function content($imageId) { // Viewをレンダリングしない $this->autoRender = false; // image_filesデータをまるっと取得する $imageFile = TableRegistry::get('ImageFiles'); // IDに紐付く画像データを取得 $fileData = $imageFile->get($imageId); if (empty($fileData)) { // 一応エラー処理 throw new NotFoundException(); } // 画像表示 $this->response->type($fileData->content_type); $this->response->body(stream_get_contents($fileData->image_data)); } }
ポイントは特にありません。
強いて言えば、レンダリングしない部分だけじゃないかなと。
あとはよくある画像表示処理です。
このコントローラをView側で呼んであげれば画像が表示されると思います。
View側も一応記載しておきます。
<?php <img src="<?php echo $this->Url->build(["controller" => "ImageFiles", "action" => "content", 12345]); ?>" class="img-rounded img-responsive" <!-- ここのClass指定はBootstrap3用 --> alt="画像12345です" />
上の例だとimage_files.id = 12345の画像を指定しています。
altは適当に記載していますが、実際はちゃんと入れないとグーグル先生がクローリングしてきた時に叱られます。
出来上がったソースを見ると、CakePHP2の頃とほとんど変わりませんでした。
が、とりあえず画像は表示できたのでよしとします。