STEP2-7. 画像をアップロードしてみよう

Laravelで画像をアップロードして表示する機能を作ってみましょう。
まずはViewでフォームを作ってみます。

フォーム作成

resources/views/home.blade.php を作成

file_path:projectname/src/resources/views/home.blade.php
<!-- エラーメッセージ。なければ表示しない -->
@if ($errors->any())
<ul>
    @foreach($errors->all() as $error)
    <li>{{ $error }}</li>
    @endforeach
</ul>
@endif

<!-- フォーム -->
<form action="{{ url('upload') }}" method="POST" enctype="multipart/form-data">

    <!-- アップロードした画像。なければ表示しない -->
    @isset ($filename)
    <div>
        <img src="{{ asset('storage/' . $filename) }}">
    </div>
    @endisset

    <label for="photo">画像ファイル:</label>
    <input type="file" class="form-control" name="file">
    <br>
    <hr>
    {{ csrf_field() }}
    <button class="btn btn-success"> Upload </button>
</form>

コントローラ作成

次は作成したフォームを呼び出すコントローラを作ってみます。

app/Http/Controllers/HomeController.php を作成

file_path:projectname/src/app/Http/Controllers/HomeController.php
<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('home');
    }
}

home.blade.php を呼び出すだけです。
これだけではまだ画面表示ができないので次にRouteを追加します。

Route追加

routes/web.php の最後の行に追加

file_path:projectname/src/routes/web.php
Route::get('/', 'HomeController@index');

ようやく画面表示の準備ができたのでアプリケーションを起動してみましょう

$ php artisan serve

ブラウザで http://localhost:8000/ にアクセスすると下記のような画面が表示されます。

localhost_8000_-_vivaldi

アップロード実装

Uploadボタンに対応するコントローラの処理を追加してみましょう。

app/Http/Controllers/HomeController.php に追加

file_path:projectname/src/app/Http/Controllers/HomeController.php
    /**
     * ファイルアップロード処理
     */
    public function upload(Request $request)
    {
        $this->validate($request, [
            'file' => [
                // 必須
                'required',
                // アップロードされたファイルであること
                'file',
                // 画像ファイルであること
                'image',
                // MIMEタイプを指定
                'mimes:jpeg,png',
            ]
        ]);

        if ($request->file('file')->isValid([])) {
            $path = $request->file->store('public');
            return view('home')->with('filename', basename($path));
        } else {
            return redirect()
                ->back()
                ->withInput()
                ->withErrors();
        }
    }

バリデーションで正しいファイルがアップロードされたかを検証し、
問題がなければ store() メソッドを使い storage/app/public/ に保存します。
その後画面で画像を表示するためにファイル名を取得し、ビューを表示させています。

upload メソッドが追加されたのでRouteも追加しておきましょう。

routes/web.php の最後の行に追加

file_path:projectname/src/routes/web.php
Route::post('/upload', 'HomeController@upload');

動作確認

ブラウザで http://localhost:8000/ にアクセスしファイルを選択し Upload ボタンをクリックします。
ローカル上の storage/app/public/ には問題なく画像がアップロードされましたが、
ブラウザ上では下記のように画像が表示されないと思います。

localhost_8000_upload_-_vivaldi

これはLaravelのデフォルトでは storage/app/public/ 配下はWebからのアクセスが許可されていません。
Webからのアクセスを許可するために下記コマンドを打ってみましょう。

$ php artisan storage:link

これで public/storage から storage/app/public へシンボリックリンクが張られ、Webからアクセスできるようになりました。
再度ファイルをアップロードして動作を確認してみましょう。

localhost_8000_upload_-_vivaldi

課題

アップロードした直後の画像を表示するまでは実装できましたが、
これまでにアップロードした全ての画像を表示するには画像の情報をDB等に保存する必要があります。
画像情報を保存するテーブルを作成し、コントローラから画像のパス情報を保存して一覧表示も試してみましょう。

results matching ""

    No results matching ""