LoginSignup
145
151

More than 5 years have passed since last update.

Laravelで画像ファイルアップロードをする簡単なサンプル

Last updated at Posted at 2017-01-06

Laravelを使ってユーザーのavatar画像をアップロードする想定で、アップロード機能のサンプルを実装してみます。

開発環境

  • Laravel 5.3
  • Laravel Homestead
    • PHP7.1系
    • MySQL 5.7系
    • Nginx

ベースとなる画面をmakeする

$ php artisan make:auth

するとこれだけのファイルが書き出されます。

    new file:   app/Http/Controllers/HomeController.php
    new file:   resources/views/auth/login.blade.php
    new file:   resources/views/auth/passwords/email.blade.php
    new file:   resources/views/auth/passwords/reset.blade.php
    new file:   resources/views/auth/register.blade.php
    new file:   resources/views/home.blade.php
    new file:   resources/views/layouts/app.blade.php
    modified:   routes/web.php

DBのmigrationも実行しておきましょう。

$ php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table

ここまでやると、ブラウザからアクセスしたときに右上に REGISTER というリンクができているので、画面に従ってユーザー登録&ログインします。

(前提環境準備終了)これからが本番です。

フォームを作成する

ファイルアップロードするフォームを追加します。
ここでは説明を省略するため、Dashboard画面に追加しますがユーザー情報変更画面などに追加するのが良いでしょう。

(抜粋)resources/views/home.blade.php
{!! Form::open(['url' => '/upload', 'method' => 'post', 'files' => true]) !!}

{{--成功時のメッセージ--}}
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
{{-- エラーメッセージ --}}
@if ($errors->any())
    <div class="alert alert-danger">
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
    </div>
@endif

<div class="form-group">
    @if ($user->avatar_filename)
        <p>
            <img src="{{ asset('storage/avatar/' . $user->avatar_filename) }}" alt="avatar" />
        </p>
    @endif
    {!! Form::label('file', '画像アップロード', ['class' => 'control-label']) !!}
    {!! Form::file('file') !!}
</div>

<div class="form-group">
    {!! Form::submit('アップロード', ['class' => 'btn btn-default']) !!}
</div>
{!! Form::close() !!}

Routeを追加

(末尾に追加)routes/web.php
Route::post('/upload', 'HomeController@upload');

Controllerを実装

リファクタリングの余地はたくさんありますが、ここではかんたんな実装ということでControllerに処理を書いていきます。

app/Http/Controllers/HomeController.php
<?php

namespace App\Http\Controllers;

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

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $user = User::find(auth()->id());

        return view('home', compact('user'));
    }


    /**
     * ファイルアップロード処理
     */
    public function upload(Request $request)
    {
        $this->validate($request, [
            'file' => [
                // 必須
                'required',
                // アップロードされたファイルであること
                'file',
                // 画像ファイルであること
                'image',
                // MIMEタイプを指定
                'mimes:jpeg,png',
                // 最小縦横120px 最大縦横400px
                'dimensions:min_width=120,min_height=120,max_width=400,max_height=400',
            ]
        ]);

        if ($request->file('file')->isValid([])) {
            $filename = $request->file->store('public/avatar');

            $user = User::find(auth()->id());
            $user->avatar_filename = basename($filename);
            $user->save();

            return redirect('/home')->with('success', '保存しました。');
        } else {
            return redirect()
                ->back()
                ->withInput()
                ->withErrors(['file' => '画像がアップロードされていないか不正なデータです。']);
        }
    }
}

Migration

usersテーブルにカラムを追加してavatar画像のファイル名を保存することにしたので、Migrationファイルを作成します。

$ php artisan make:migration add_avater_filename --table=users
<?php

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

class AddAvatarFilename extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('avatar_filename', 100);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('avatar_filename');
        });
    }
}

マイグレーションファイルを記述したら、実行します。

$ php artisan migrate

storageを公開するためのシンボリックリンク作成

$ php artisan storage:link

このコマンドで public/storage から storage/public にシンボリックリンクが作成されます。

動作確認

さて、ここまで実装すればブラウザからファイルアップロードができるようになっているはずです。

スクリーンショット 2017-01-06 13.29.15.png

145
151
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
145
151