Laravel5入門として画像投稿機能付き掲示板作成を目指す：画像投稿偏(base64使用)

[ララ帳様](https://laravel10.wordpress.com/)のおかげで、Laravel5の簡単な機能に色々触ることができました。

今回は画像投稿機能をbase64を利用して触ってみたいと思います。
※lightboxで画像を表示する方法は[ここ](http://qiita.com/banaba0207/items/6518f4790f31ce6db1a2)に新しく記事を作成しました。
ググり力の至らなさで体系的にまとめられているサイトを見つけることができなかったので、試行錯誤でやっていきたいと思います。

#DBの設定
- 新たに `fig_orig(オリジナル画像データ)` 等のカラムを定義したマイグレーションファイルを作成し、マイグレーションを実行しなおしました
- また、テーブル名変更（articles -> posts）に伴い、前回作成したファイルを posts 仕様へと書き直しました

```php.database/migrations/2016_02_10_162119_create_posts_table.php  
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('contributor')->nullable();
            $table->string('title');
            $table->string('body');
            $table->string('fig_name')->nullable(); //add
            $table->string('fig_mime')->nullable(); //add
            $table->binary('fig_orig')->nullable(); //add
            $table->binary('fig_thumbnail')->nullable(); //add
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::drop('posts');
    }
}
```

#投稿フォームの編集
- 画像投稿フォームを作成するため以下のことを行いました
    - Form::open に 'files' => 'true' を設定
    - Form::file('data') で投稿フォームを作成

```php.resources/views/posts/create.blade.php    
~~
    {!! Form::open(['route' => 'posts.store', 'files' => 'true']) !!}
    @include('posts.form', ['title' => null, 'submitButton' => 'Add post'])
    {!! Form::close() !!}
~~
```

```php.resources/views/posts/form.blade.php  
~~
    {!! Form::label('fig_orig', 'Figure:') !!}
    {!! Form::file('data') !!}
~~
```

投稿フォームが実装できました。

#コントローラーの編集
- store 関数をいじります
    1. Postインスタンスを作成
    2. 作成したPostインスタンスに request の内容をfillする（入れ込む）
    3. $imageが空でなければif文の中へ
    4. アップロードファイルの拡張子（MIMEタイプ）を取得
    5. jpg,png,gif以外の形式であれば、前画面へリダイレクトし、エラーメッセージを表示する
    6. ビューでForm::file でアップロードされた `data` にはいっている内容を文字列に変換
    7. 変換した文字列をPostインスタンスの画像カラムに保存
    8. DBに保存
    
```php.resources/views/posts/create.blade.php  
~~
use Input;
~~
    public function store(PostRequest $request){
        //        Post::create($request->all());
        $this->post = new Post();
        $this->post->fill($request->all());

        ~~

        $image = Input::file('data');
        if(!empty($image)) {　//拡張子のチェック
            $this->post->fig_mime = $image->getMimeType();
            switch ($this->post->fig_mime) {
            case "image/jpeg": $flag = TRUE; break;
            case "image/png": $flag = TRUE; break;
            case "image/gif": $flag = TRUE; break;
            default: $flag = FALSE;
            }
            if ($flag == FALSE) { //投稿フォームに戻り、エラーメッセージの表示を行う
                \Flash::error('アップロード可能な画像ファイルは jpg, png, gif のみです。');
                return redirect()->back();
            }

            $this->post->fig_orig = file_get_contents($image);
        }

        $this->post->save();
        ~~
    }
~~
```

Inputクラスを利用するため、`config/app.php` に以下の行を追加しました。

```php.config/app.php  
~~
    'aliases' => [
        ~~
        'Input'     => Illuminate\Support\Facades\Input::class,
        ~~
    ],
~~
```

#表示編
DBに保存された画像を表示してみます。

- index.blade.php の記事表示部分をいじります
    1. `fig_orig` カラムが空か否かを判定
    2. DBには文字列形式で保存されているので、バイナリ形式に変換
    3. エンコードされたデータをpng形式で表示
        - Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式
        - MIMEによって規定されていて、7ビットのデータしか扱うことの出来ない電子メールにて広く利用されている

```php.resources/views/posts/index.blade.php  
~~
    @foreach($posts as $post)
        <post>
            <div class="panel panel-default">
              ~~
                {{-- Image view start --}}
                @if (!empty($post->fig_orig))                          //1
                    <?php
                    $image_base64 = base64_encode($post->fig_orig);    //2
                    ?>
                    <img src='data:img/png;base64,{{$image_base64}}'>  //3
                @endif
                {{-- Image view end --}}
            </div>
        </post>
    @endforeach
@endsection
```

#学びと課題
- かなりブサイクなやり方ですが、なんとかDBにアップロードした画像を保存、表示することができました、できましたが…
- 以下の課題が残っているので、随時対策していこうと思います
    - サムネイル表示
        - 画像をクリックしたときのみ、オリジナルサイズ表示
    - 表示された画像を保存すると、テキストデータになっている
        - ちゃんと画像に名前をつけて上げる必要がある・・・？
    - コントローラーのソースコードをもっとエレガントに
        - DB保存するときにもっとスマートにできる方法がありそう…

アドバイス等あれば、コメントにぜひぜひお願いいたします！！