Upload File Dengan Laravel

Pada tutorial kali ini kita akan membahas bagaimana cara upload file dengan laravel, di laravel sendiri upload file sangat mudah, karena berbasis framework yang memang tujuannya untuk mempermudah pengembangan.

Konsep tutorial upload file dengan laravel ini adalah dimana user bisa melakukan upload file beserta validasi, dimana file yang akan di upload dibatasi jenisnya sehingga tidak semua file dapat di upload ke server. Selain itu file akan disimpan di direktori yang akan di tentukan dan beberapa data dari file tersebut di simpan didatabase sehingga bisa ditampilkan di browser.

Cara Upload File Dengan Laravel

Sebelum kita memulai proses upload file sebaiknya kita buat dulu table untuk menyimpan meta data dari file tersebut, dimana mungkin kita akan membutuhkan nama file, ukuran, ekstensi file dan sebagainya.

Buatlah sebuah model dengan nama Media beserta migration (table database) dimana nantinya meta file tersebut akan disimpan didalam table media, jalankan perintah dibawah ini di terminal atau cmd anda.

php artisan make:model Media --migration

Selanjutnya pada file model migration yang ada difolder database/migrations buatlah seperti kode dibawah ini.

Schema::create('media', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('file');
    $table->string('extension');
    $table->integer('size');
    $table->string('mime');
    $table->timestamps();
});

Jika sudah selanjutnya jalankan migration dengan jalan menjalankan perintah dibawah ini.

php artian migrate

Dimana didalam table media kita akan menyimpan nama file, file (nama beserta extension), extension, size, dan mime type file yang di upload tersebut. Selanjutnya buatlah sebuah controller dengan perintah dibawah ini.

php artisan make:controller MediaController --resource

Dari perintah diatas maka akan tercipta sebuah file bernama MediaController yang terletak di folder App\Http\Controllers, buka file MediaController tersebut lalu tambahkan kode dibawah ini.

use Illuminate\Support\Facades\File;
use App\Models\Media;

Tepat dibawah kode.

use Illuminate\Http\Request;

Sehingga akan menjadi seperti kode dibawah ini.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use App\Models\Media;

class MediaController extends Controller
{
    ...
}

Selanjutnya pada method index() buatlah menjadi seperti kode dibawah ini.

public function index()
{
    $medias = Media::orderBy('created_at', 'DESC')->get();

    return view('media', compact('medias'));
}

Selanjutnya kita akan membuat layout, dimana layout ini digunakan sebagai file html terpisah yang menangani kerangka utama halaman upload ini. Buatlah sebuah file dengan nama layout.blade.php lalu simpan didalam folder resources/views dan masukkan kode dibawah ini.

<html>
    <head>
        <title>Upload File</title>
        <style>
            .container {
                position: relative;
                width: 80%;
                margin: 0 auto;
            }
            form .group {
                margin-bottom: 10px;
            }
            form .group label {
                display: inline-block;
                margin-bottom: 10px;
            }
            form .group input {
                border: 1px solid #cccccc;
                border-radius: 4px;
                display: block;
                width: 100%;
                padding: 10px;
            }
            form .group .error {
                display: inline-block;
                color: #ff0000;
                margin-top: 5px;
            }
            form .group button.save {
                background-color: #4169E1;
                border: 1px solid #325cdb;
                color: #ffffff;
                padding: 10px;
                cursor: pointer;
                border-radius: 4px;
            }
            
            form .group button.cancel {
                background-color: #4169E1;
                border: 1px solid #325cdb;
                color: #ffffff;
                padding: 10px;
                cursor: pointer;
                border-radius: 4px;
            }

            table {
                border: 1px solid #cccccc;
                margin-top: 10px;
            }
            table tr td,
            table tr th {
                border-left: 1px solid #cccccc;
                padding: 10px;
            }
            table tr td:first-child,
            table tr th:first-child {
                border-left: 0;
            }
            table tr td {
                border-top: 1px solid #cccccc;
            }
        </style>
    </head>
    <body>
        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

Jika sudah lalu buatlah sebuah file dengan nama media.blade.php lalu simpan didalam folder resources/views dan masukkan kode dibawah ini.

@extends('layout')
@section('content')
    @if(session()->has('message'))
        <p>{{ session()->get('message') }}</p>
    @endif
    <form action="{{ route('media.store') }}" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="_token" value="{{ csrf_token() }}">
        <div class="group">
            <label for="file">Upload File</label>
            <input type="file" id="file" name="file">
            @if($errors->has('file'))
                <small class="error">{{ $errors->first('file') }}</small>
            @endif
        </div>
        <div class="group">
            <button class="save">Upload</button>
        </div>
    </form>
    <table width="100%" cellpadding="0" cellspacing="0">
        <thead>
            <tr>
                <th align="left" width="50%">File</th>
                <th width="25%">Download</th>
                <th width="25%">Tindakan</th>
            </tr>
        </thead>
        <tbody>
            @if($medias->count())
                @foreach($medias as $media)
                    <tr>
                        <td>
                            <div>Nama: {{ $media->name }}</div>
                            <div>File: {{ $media->file }}</div>
                            <div>Ekstensi: {{ $media->extension }}</div>
                            <div>Ukuran: {{ $media->size }}</div>
                            <div>Mime: {{ $media->mime }}</div>
                        </td>
                        <td align="center"><a href="{{ url('uploads/' . $media->file) }}" download>Download</a></td>
                        <td align="center">
                            <button form="delete-file" onclick="return confirm('Apakah anda yakin ingin menghapus file?')">Hapus</button>
                            <form action="{{ route('media.destroy', $media->id) }}" method="post" id="delete-file">
                                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                                <input type="hidden" name="_method" value="delete">
                            </form>
                        </td>
                    </tr>
                @endforeach
            @else
                <tr>
                    <td align="center" colspan="3">Belum ada file</td>
                </tr>
            @endif
        </tbody>
    </table>
@endsection

Jika semuanya sudah, lalu buka file web.php yang berada didalam folder routes, lalu tambahkan kode dibawah ini.

Route::resource('media', MediaController::class);

Selanjutnya jalankan perintah dibawah ini di terminal atau CMD jika anda menggunakan windows.

php artisan serve

Perintah diatas agar projek laravel anda dapat diakses melalui port yang sudah ditentukan oleh artisan serve tersebut sehingga anda dapat mengakses halaman upload dengan url http://127.0.0.1:8000/media dan seharusnya di browser anda akan muncul seperti gambar dibawah ini.

upload file dengan laravel

Jika sudah sesuai dengan gambar diatas selanjutnya kita akan membuat proses upload, buka kembali file MediaController lalu pada bagian store() ubahlah menjadi kode seperti dibawah ini.

public function store(Request $request)
{
    $request->validate([
        'file' => 'required|mimes:doc,docx,xls,xlsx,pdf,jpg,jpeg,png,bmp'
    ]);

    if($request->hasFile('file')) {
        $uploadPath = public_path('uploads');

        if(!File::isDirectory($uploadPath)) {
            File::makeDirectory($uploadPath, 0755, true, true);
        }

        $file = $request->file('file');
        $explode = explode('.', $file->getClientOriginalName());
        $originalName = $explode[0];
        $extension = $file->getClientOriginalExtension();
        $rename = 'file_' . date('YmdHis') . '.' . $extension;
        $mime = $file->getClientMimeType();
        $filesize = $file->getSize();

        if($file->move($uploadPath, $rename)) {
            $media = new Media;
            $media->name = $originalName;
            $media->file = $rename;
            $media->extension = $extension;
            $media->size = $filesize;
            $media->mime = $mime;
            $media->save();

            return redirect()->back()->with('message', 'Berhasil, file telah di upload');
        }

        return redirect()->back()->with('message', 'Error, file tidak dapat di upload');
    }

    return redirect()->back()->with('message', 'Error, tidak ada file ditemukan');
}

Pada kode diatas terlihat proses tersebut melakukan validasi dan hanya mengijinkan beberapa jenis file saja seperti doc, docx, xls, xlsx, pdf, jpg, jpeg, png, bmp. Lalu agak kebawah sedikit kode diatas terlihat akan memeriksa folder yang sudah ditentukan tersebut, dimana apabila tidak ada folder yang dituju maka otomatis akan dibuatkan dengan permission 755.

Selanjutnya file akan di rename menjadi nama acak dengan prefix file_ akan tetapi nama asli dari file tersebut akan tetap disimpan di database, sementara file akan disimpan di folder public/uploads.

Untuk mengecek validasi apakah bekerja atau tidak, silahkan anda upload file selain file yang diijinkan diatas, maka seharusnya akan muncul pesan error seperti pada gambar dibawah ini.

upload file dengan laravel

Jika sudah sesuai, silahkan anda coba upload sebuah file dengan ekstensi yang diijinkan seperti file dokumen dan gambar, apabila berhasil maka file akan ditampilkan tepat pada tabel dibawahnya seperti pada gambar dibawah ini.

Upload file dengan laravel

Yang terakhir adalah mengaktifkan tombol hapus, tombol hapus digunakan untuk menghapus meta file di database dan file yang terdapat didalam folder public/uploads.

Buka kembali file MediaController lalu pada bagian method destroy() buatlah seperti kode dibawah ini.

public function destroy($id)
{
    $media = Media::find($id);

    if($media) {
        $file = public_path('uploads/' . $media->file);

        if(File::exists($file)) {
            File::delete($file);
        }

        $media->delete();

        return redirect()->back()->with('message', 'Berhasil, file berhasil dihapus');
    }

    return redirect()->back()->with('message', 'Error, tidak ada file ditemukan');
}

Pada kode diatas dimana sebelum file dan data dihapus maka kode akan memeriksa apakah file yang dituju ada atau tidak dalam folder public/uploads tersebut, jika ada maka akan dihapus beserta data yang ada didalam database.

Jika kode diatas telah selesai anda tulis maka silahkan anda klik tombol hapus, jika berhasil data akan hilang dari table dan file akan dihapus dari folder public/uploads.

Sekian tutorial ini semoga bermanfaat.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.