Edited at

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

More than 1 year has passed since last update.

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