Hokma School :: Course 2 Laravel

Laravel 09. File Upload

테디아저씨 2026. 5. 8. 09:07

 

 

resources/member/myphoto.blade.php

        <div class="row mt-5">   
            <h1>
                My Profile
            </h1>
        </div>
        <div class="row mt-2">  
            <div class="col-md-4">
                이름<br/>
                <span>{{ $user['name'] }}</span>
            </div>
            
            <div class="col-md-8">


                <form action="{{ route('myphoto.submit') }}" method="POST" enctype="multipart/form-data">
                    @csrf
                    <input type="file" name="photo" class="form-control" accept="image/*">
                    <button type="submit" class="btn btn-primary mt-2">업로드</button>
                </form>            
            </div>
        </div>

 

Model

php artisan make:migration photo_to_users

 

<?php

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

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

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

 

 

routes/web.php

Route::middleware('auth')->group(function () {
    Route::get('/dashboard', [IndexController::class, 'dashboard'])->name('dashboard');
    
    Route::get('/myphoto', [UserController::class, 'myphoto'])->name('myphoto');
});

 

    public function myphoto(){

        if( Auth::check() ){
            $user = Auth::user();
        } else {
            $user = [];
        }
        
        return view('member.myphoto', [ 'user' => $user ]);
    }

 

 

UserController.php

    public function myphoto_submit(Request $request)
    {
        
        $photo = $request->file('photo');

        dd($photo);

    }

 

dd 로 데이터를 확인하자

 

파일 저장

라라벨의  스토리지를 직접 접근하지 않습니다.

 

심볼릭 링크 생성

라라벨은 보안을 위해

php artisan storage:link

 

 

Why?

Storage 는 직접접근이 불가능합니다.

 


Laravel Path

storage/app/public

 

Web Path

public/storage

 

 

config/filesystem.php

'disks' => [

    'public' => [
        'driver' => 'local',
        'root' => storage_path('app/public'),
        'url' => env('APP_URL').'/storage',
        'visibility' => 'public',
    ],

]

 

 

 

UserController.php

    public function myphoto_submit(Request $request)
    {
        $request->validate([
            'photo' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);
        
        $photo = $request->file('photo');

        // folder, disk
        $path = $photo->store('photos', 'public');    
    
    	// save file
        $user = Auth::user();
        
        // update to DB
        $user->photo = $path;
        $user->save();      

        return redirect()->route('myphoto')->with('success', 'Photo uploaded successfully');

    }

 

Validation

$request->validate([
    'image' => 'required|image|mimes:jpg,png,jpeg|max:2048'
]);

 

  • image → 이미지 파일만
  • mimes → 확장자 제한
  • max → 용량 제한

 

파일저장

$path = $photo->store('photos', 'public');

 

'photos'  :  saved folder

'public'  :  used disk

 

파일확인

 

File

storage/app/public/images

 

 

디비저장

// update to DB
$user->photo = $path;
$user->save();

 

@if( isset($user) && !empty($user) && isset($user['photo']) && !empty($user['photo']) )
    <img src="{{ asset('storage/'.$user['photo']) }}">
@else
    <span>No photo</span>
@endif

 

or

//Controller
$img_url = "";

//view
<img src="{{ asset($img_url) }}">

 

 

  • 파일명변경
$fileName = time().'_'.$photo->getClientOriginalName();
$path = $photo->storeAs('photos', $fileName, 'public');

 

기타 다른 파일명사용

$fileName = uniqid().'.'.$file->getClientOriginalName();
// 663ab12cd.test.jpg

$fileName = uniqid().'.'.$file->extension();
// 663ab12cd.jpg

 

** 주의 : 저장한 파일명을 그대로 디비에 저장

 

 

파일삭제

views/member/myphoto.blade.php

@if( isset($user) && !empty($user) && isset($user->photo) && !empty($user->photo) )
    <img src="{{ asset('storage/'.$user['photo']) }}" alt="프로필" class="img-thumbnail mb-2 d-block">
    <form action="{{ route('myphoto.delete') }}" method="post" class="mb-3">
        @csrf
        <button type="submit" class="btn btn-danger">삭제</button>
    </form>
@else
    <span>No photo</span>
@endif

 

routes/web.php

Route::delete('/myphoto/delete', [UserController::class, 'myphoto_delete'])->name('myphoto.delete');

 

UserController.php

use Illuminate\Support\Facades\Storage;
...



    public function myphoto_delete(Request $request)
    {
        $user = Auth::user();
        if( isset($user) && !empty($user) && isset($user->photo) && !empty($user->photo) ){
            Storage::disk('public')->delete($user->photo);

            $user = Auth::user();
            $user->photo = null;
            $user->save();

        }

        return redirect()->route('myphoto')->with('success', 'Photo deleted successfully');
    }

 

 

## 과제

 

1. Truck Image Upload

2. 이미지의 경우 리사이징