「Herokuにデプロイしたページの画像が表示されない！？」を解決する AWS S3 超カンタン利用法

どうも、Hiroyukiです！

本日は、[別の記事](https://qiita.com/Hiroyuki-Hiroyuki/items/42d9c8a797ea51fb7a51)でも少し触れた、
###Herokuで画像を表示させるための「AWS S3」超カンタン利用法！
を解説しようと思います＾＾

![s3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489124/c004590d-cf1e-f62b-fa48-2ce10ab60956.png)

#「画像が表示されない！？」問題発生

自分のオリジナルサービスが完成！！
「よーし、あとはHerokuにデプロイするだけだから、余裕やな〜〜」

と思ってたのも束の間、
###「Heroku上に、、、ガガガ、、画像が表示されませーーーん。。。。
###　オワタ・・・（涙目）」

となったので、ググりますと何と、
###「Herokuに画像をアップしても、一定時間で消去される」
###　という仕様なのだぁああーーーーと判明（絶望・・・！）

まあ、落ち込んでてもしゃーないので、対策方法をググって見つけたのが「AWS S3」。

###ググってたら結構難しめな記述でS3と連携させてる記事も多かったので、
###（初心者向けに）超簡単なS3利用方法を解説しませう！


#AWS S3 でバケットを作成

まず、S3とは、アマゾンが提供するストレージ機能です。
###要するに、「画像とか貯めとけますよ〜」っていうサービス。

手順としては、以下の通り。

###1.AWSアカウント作成
カンタンにできますので、下記をご覧ください〜
https://aws.amazon.com/jp/register-flow/

登録時に下記のキーが作られるので
####　・Access key ID
####　・Secret access key
これをメモしておいて下さいね〜！


###２.S3バケット作成
AWSアカウントでログイン後、S3のバケットを作ります。
詳しくは下記URLへ。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/create-bucket.html

要約しますと

###・任意のバケット名を決める
###・リージョン（地域）を選ぶ
###・プロパティを設定する（基本初期設定のままで問題ないかと）

この３点を設定するだけで、S3の設定が完了しちゃいますっ！

#AWS SDK for PHPをインストール

次は、AWS SDK for PHPを composer でインストールしていきます！

```php
$ composer install aws/aws-sdk-php
```

#Herokuの環境変数を設定

Herokuの環境変数を下記の様に設定します！

```php
heroku config:set AWS_ACCESS_KEY_ID='AWSで作成したAccess key ID'
heroku config:set AWS_SECRET_ACCESS_KEY='AWSで作成したSecret access key'
heroku config:set AWS_DEFAULT_REGION='作成したバケットのリージョン名'
heroku config:set AWS_BUCKET_BUCKET='作成したバケット名'
```

#画像アップロード機能を実装

さて、いよいよアップロード処理をいじっていきます。
でも、下記の様に書けば、めちゃくちゃカンタンなはず！

今回は
###「アイコン画像を登録して、表示させるまでのやり方」
でつくってみました～


###コントローラー：S3 に保存させる処理
PhotosController.php

```php
class PhotosController extends Controller
{
    public function storeIcon(Request $request)
    {
            $file=$params['photo'];

            // s3のuploadsファイルに追加
            $path = Storage::disk('s3')->put('/icon_images',$file, 'public');

            // パスを、ユーザのicon_image_urlというカラムに保存
            $user=\Auth::user();
            $user->icon_image_url = $path;
            $user->save();

            return view('setting.channel');
    }
```
ミソは、
###1. S3 の icon_images というフォルダに画像を保存！
（フォルダに入れても、S3上に裸のファイルを入れてもいいでしょう）
###2. S3 のパスを$pathという変数に代入
###3. その$pathをユーザの icon_image_url というカラムに保存
という流れです！

###ブレイド：アイコン画像をPOSTして、表示させるまでの処理
channel.blade.php

```php
<h2>アイコン画像を変更</h2>

<span width="100px" height="100px">
   <img class="rounded" src="{{ Storage::disk('s3')->url(Auth::user()->icon_image_url) }}">
</span>

<figcaption>現在のアイコン画像</figcaption>

<form method="POST" action="/storeIcon" enctype="multipart/form-data">
 {{ csrf_field() }}
  <input type="file" name="photo">
  <input type="submit" value="更新する？" class="button btn">
</form>
```
ここでは、S3 のパスをimgのsrcに入れ込みます！


###ルーター：ルーティング処理
web.php

```
Route::post('storeIcon','PhotosController@storeIcon')->name('icon.store');
```

以上！

###結構簡単じゃないですか？
まあ、僕もこういうところでつまづいて止まってたんですけどね。。。（汗）


#補足：　S3 アクセス権限について

ちなみに補足ですが、
上記コードのアップロード機能を経由した画像等は、画像のパスによって
（普通は問題なく）画像にアクセスが可能だと思うのですが、

###自分で「AWS S3のコンソール画面」からに画像等をアップロードした場合
###→アクセス権限が許可されておらず、画像が表示されない！！

という問題が起こる時があります（実体験！）

###ボクもこれに悩みまくった。。。。

同じことでお悩みの方がいましたら、
下記の通りやっていただくと、画像が正常に表示されますので、要チェック！


###１．各画像の詳細画面から、「アクセス権限」のタブを押す
###→　パブリックアクセス　に行く
![publicaccess.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489124/f7d39b56-3442-947d-4a2d-78dab65da2f2.png)
###２．（↑コチラ）Everyone をクリック！

![yomitori.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489124/fd807b8d-14aa-ce4e-a727-4f5688c0a51a.png)

###３．オブジェクトの読み取り　にチェックを入れる！


こういう流れです。

流れを整理すると簡単に見えるんですが、細かいところでつまづいちゃいますよね～。
###仕方ない、人間だもの。。。。


あと、上記コードを使って S3 アップロードしている
###[ボクのオリジナルサービス](http://youtubematome.herokuapp.com/) ←クリック
も気になる方は参考までに、チェックしてみてくださいね～～！

ではまた！Hiroyukiでした！！＾＾