LoginSignup
17
18

More than 3 years have passed since last update.

【コピペでOK】Laravelでユーザーテーブル編集と画像アップロード

Last updated at Posted at 2019-06-23

はじめに

画像アップロードって意外とめんどくさいので、コピペレベルで
実装できるサンプルを作りましたので、ご紹介いたします。

こんな方におすすめ

・Laravelを一通り書籍等でおこない、画像処理に困っている方
・特に「PHPフレームワーク Laravel入門 単行本 掌田津耶乃」(青い表紙)でLaravelを学ばれた方 ※この書籍では画像アップロードやり方が載ってない

つくるもの

せっかくなので、デフォルトで作成される「users_table」に「thumbnail」カラムを追加して画像をアップできるようにしていきたいと思います。

要件
①「name」カラムをUpdate
②追加する「thumbnail」カラムをUpdate

1.png
スクリーンショット 2019-06-23 15.06.58.png
3.png

手順レシピ

1.準備
Laravelを新規構築

$ php artisan make:auth

$ php artisan migrate

registerからユーザー登録する
大量にテストデータを挿入したい場合はシーディングを利用
※Userモデルは「make:auth」で自動的に生成されます
※Userテーブル以外の場合は各モデルを生成してください

$ php artisan make:migration add_thumbnail --table=users
database/migrations/xxxx_xx_xx_xxxxxx_add_thumbnail.php
// 中略
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('thumbnail')->nullable();
    });
}
// 中略
public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('thumbnail');
    });
}

registerで登録できなくなるのでnullをOKにしておきます。
register側でthumbnail登録できるようにしておけばnullableはなくてOK。

$ php artisan migrate

2.コントローラー実装

$ php artisan make:controller UserController
app/Http/Controllers/UserController
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Validator;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Storage;

class UserController extends Controller
{
    public function index(Request $request){
        $authUser = Auth::user();
        $users = User::all();
        $param = [
            'authUser'=>$authUser,
            'users'=>$users
        ];
        return view('user.index',$param);
    }

    public function userEdit(Request $request){
        $authUser = Auth::user();
        $param = [
            'authUser'=>$authUser,
        ];
        return view('user.userEdit',$param);
    }

    public function userUpdate(Request $request){
        // Validator check
        $rules = [
            'user_id' => 'integer|required',
            'name' => 'required',
        ];
        $messages = [
            'user_id.integer' => 'SystemError:システム管理者にお問い合わせください',
            'user_id.required' => 'SystemError:システム管理者にお問い合わせください',
            'name.required' => 'ユーザー名が未入力です',
        ];
        $validator = Validator::make($request->all(),$rules,$messages);

        if($validator->fails()){
            return redirect('/user/userEdit')
                ->withErrors($validator)
                ->withInput();
        }

        $uploadfile = $request->file('thumbnail');

          if(!empty($uploadfile)){
            $thumbnailname = $request->file('thumbnail')->hashName();
            $request->file('thumbnail')->storeAs('public/user', $thumbnailname);

            $param = [
                'name'=>$request->name,
                'thumbnail'=>$thumbnailname,
            ];
          }else{
               $param = [
                    'name'=>$request->name,
               ];
          }

        User::where('id',$request->user_id)->update($param);
        return redirect(route('user.userEdit'))->with('success', '保存しました。');
    }
}

Auth::user() → 認証ユーザー取得(今回はこっちを使用)
User::all() → ユーザー全て取得

2.ルーティング

routes/web.php
// 追加
Route::get('/user', 'UserController@index')->name('user.index')->middleware('auth');
Route::get('/user/userEdit', 'UserController@userEdit')->name('user.userEdit')->middleware('auth');
Route::post('/user/userEdit', 'UserController@userUpdate')->name('user.userUpdate')->middleware('auth');

3.ビュー実装
共通レイアウトは初期で入っている「app.blade.php」を利用することとします

resources/views/user/index.blade.php
@extends('layouts.app')
@section('title','ユーザー情報')
@section('content')
<div class="container">
  <table class="table table-striped table-hover">
  <thead>
  <tr>
    <th></th>
    <th>ID</th>
    <th>名前</th>
    <th>メールアドレス</th>
    <th></th>
  </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <div>
        @if(!empty($authUser->thumbnail))
        <img src="/storage/user/{{ $authUser->thumbnail }}" class="thumbnail">
        @else
        画像なし
        @endif
        </div>
      </td>
      <td>{{ $authUser->id }}</td>
      <td>{{ $authUser->name }}</td>
      <td>{{ $authUser->email }}</td>
      <td>
      <a href="{{ route('user.userEdit') }}" class="btn btn-primary btn-sm">編集</a>
      </td>
    </tr>
  </tbody>
  </table>
</div>  
@endsection
resources/views/user/userEdit.blade.php
@extends('layouts.app')
@section('title','ユーザー情報変更')

@section('content')
<div class="container">
    @if (session('success'))
    <div class="alert alert-success">{{ session('success') }}</div>
    @endif

    <div class="topWrapper">
        @if(!empty($authUser->thumbnail))
            <img src="/storage/user/{{ $authUser->thumbnail }}" class="editThumbnail">
        @else
        画像なし
        @endif
    </div>

    <form method="post" action="{{ route('user.userUpdate') }}" enctype="multipart/form-data">
        {{ csrf_field() }}

        <input type="hidden" name="user_id" value="{{ $authUser->id }}">
        @if($errors->has('user_id'))<div class="error">{{ $errors->first('user_id') }}</div>@endif

        <div class="labelTitle">Name</div>
        <div>
            <input type="text" class="userForm" name="name" placeholder="User" value="{{ $authUser->name }}">
            @if($errors->has('name'))<div class="error">{{ $errors->first('name') }}</div>@endif
        </div>

        <div class="labelTitle">Thumbnail</div>

        <div>
            <input type="file" name="thumbnail">
        </div>

        <div class="buttonSet">
            <input type="submit" name="send" value="ユーザー変更" class="btn btn-primary btn-sm btn-done">
            <a href="{{ route('user.index') }}" class="btn btn-primary btn-sm">戻る</a>
        </div>
    </form>
</div>
@endsection

軽くCSSも作成したので、追加

public/css/style.css
.topWrapper {
    width: 150px;
    margin: 0 auto;
}

.thumbnail {
    width: 30px;
    height: 30px;
    object-fit: cover;
    border-radius: 50%;
}

.editThumbnail {
    width: 150px;
    height: 150px;
    object-fit: cover;
    border-radius: 50%;
}

.buttonSet {
    margin: 30px 0 0 0;
    text-align: center;
}

.labelTitle {
    color: #006DD9;
    margin: 20px 0 5px 0;
}

input[class="userForm"] {
    width: 100%;
    padding: 5px 0 5px 10px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    transition: 1s;
}
input[class="userForm"]:focus {
    background: #87ceeb;
}

.btn-done {
    background: #dc143c;
    border: 1px solid #dc143c;
}
.btn-done:hover {
    background: #cc1237;
    border: 1px solid #cc1237;
}

.error {
    font-size: 15px;
    font-weight: 100;
    color: #cc1237;
}
resources/views/layouts/app.blade.php
<!--追加-->
<link href="{{ asset('css/style.css') }}" rel="stylesheet">

シンボリックリンク作成

画像に関して、
アップロードされるところはstorageフォルダですが、
Laravelではpublicフォルダを参照されるので、
シンボリックリンクを作成する必要がある。

$ php artisan storage:link

動作確認

以上で画像アップロードができるようになったかと思います。

17
18
0

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
17
18