自分はLaravelで画像掲示板のようなものを作成していた。すると、ローカルでは画像が問題なく表示されていたのに、herokuにデプロイすると投稿された画像が「リンク切れ」状態になって表示されないという事象が起きた。そこで、その問題の原因と解決策についてまとめる。
原因はシンプルにHerokuでは画像が生成されないということでした。 少し実装の話をさせてもらうと、今回の画像掲示板では画像をstorageに保存して、そのパスをDBに保存して管理していました。しかし、上記したようにherokuでは画像(ファイル)の生成ができないとのことです。(/tmpというフォルダにはファイルが生成できるようだが、それも一定時間で消えてしまうので根本的な解決にならない。)そのため、画像がリンク切れになってしまっていたようです。
「Herokuの仕様だから仕方ない、別にリリースするアプリじゃないし」と妥協してもよかったのですが、せっかくなのでどうにか足掻いてみることにしました。結果から言うと成功しました。どうやったかと言うと「画像自体をバイナリデータとしてDBに入れる」ことにしました。
下記にDBにバイナリを保存する方法を記述します。 詳細記事←ここに詳細は書いてあります。
手順
画像データ保存のためのカラムを用意する
Schema::create('bbs', function (Blueprint $table) {
/*カラム*/
$table->text('image'); // 画像に関する記述
});
バイナリ型もあったんですけど、MySQLの挙動とは違い、配列になったりで扱い不明だったのでtextにしました。
画像のバイナリを取得する
file_get_contents($request->image->getRealPath());
viewのフォームで「image」と言うname属性で画像を受け取るようにしたので、このような記述でバイナリデータが取れます。
base64でエンコードする
$image_binary = base64_encode(file_get_contents($request->image->getRealPath()));
ただのバイナリではHTMLで表示できないのでエンコードした状態で保存します。
そのデータをDBに保存する
Model::insert(["image" => $image_binary]);
そのバイナリをDBに保存。
viewで表示する
<img src="data:image/png;base64,<?= $image ?>">
表示するときは取ってきたbase64のデータをこんな感じで書くと表示されます。 以上。