Upload File di Laravel 5

Upload File di Laravel 5

Dalam sebuah web aplikasi, meski tidak bersifat wajib namun fitur upload file merupakan sebuah fitur yang banyak digunakan berdasarkan peruntukannya masing-masing, seperti: upload foto profil, attach email, bukti pembayaran, dan lain sebagainya. Maka pada kesempatan kali ini, kita akan membahas bagaimana meng-handle file di Laravel sehingga file tersebut dapat digunakan sebagaimana mestinya.

Laravel memberikan banyak pilihan yang dapat digunakan oleh penggunanya, diantaranya, direktori penyimpanan file dapat diletakkan di storage, public atau external disk. Karena untuk kebutuhan pembelajaran, maka ketiganya akan diterapkan pada artikel kali ini.

Baca Juga: Sweet Alert & Flash Message

Basic Uploading

Sebelum memulai rangkaian beberapa method yang dapat digunakan sebagai pilihan untuk meng-handle file di Laravel, maka install Laravel terlebih dahulu dengan command:

composer create-project --prefer-dist laravel/laravel upload

Metode pertama yang akan digunakan melalui HTTP request tanpa bantuan package untuk menerima dan mengelola file yang akan di-upload, modifikasi view welcome.blade.php dengan membuat form upload menjadi seperti berikut:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>File uploads</title>
</head>
<body>
    <form action="/uploads" enctype="multipart/form-data" method="POST">
        {{ csrf_field() }}
        <p>
            <label for="photo">
                <input type="file" name="photo" id="photo">
            </label>
        </p>
        <button>Upload</button>
    </form>
</body>
</html>

Penjelasan: Code diatas hanyalah sebuah form html biasa dengan mode enctype="multipart/form-data" agar dapat mengirim file dan method POST. {{ csrf_field() }} akan meng-generate hidden form yang berisi token sebagai ketentuan yang telah ditetapkan Laravel untuk sebuah form.

Pada form di atas telah didefinisikan bahwa route selanjutnya yang akan dituju adalah uploads maka buka routes/web.php kemudian tambahkan code berikut:

...
​
use Illuminate\Http\Request;
​
Route::post('/uploads', function(Request $request) {
    $file = $request->file('photo')->store('uploads');
    return dd($file);
});

Penjelasan: URI /uploads didefinisikan sebagai method POST yang akan menerima file yang dikirimkan dari form upload telah dibuat, kemudian disimpan kedalam folder uploads. Jika dilihat kedalam config/filesystems.php, maka secara default local disk berisi direktori storage_path('app') yang artinya file yang telah diupload akan diletakkan kedalam direktori: storage/app/uploads.

Lebih jauh lagi, file yang diterima dapat dimanipulasi sesuai keinginan, seperti default name dapat diubah sesuai kebutuhan:

Route::post('/uploads', function(Request $request) {
    $file = $request->file('photo');
    $name = 'daengweb-' . \Carbon\Carbon::now()->format('Y-m-dH:i:s') . '.' . $file->getClientOriginalExtension();
    $path = $file->storeAs('uploads', $name);
    return dd($path);
});

Penjelasan: Perbedaan yang mencolok adalah pada code yang berfungsi untuk meng-custom nama file, dengan menggunakan prefix daengweb- kemudian di ikuti dengan waktu saat file di upload menggunakan Carbon, lalu ditutup dengan memberikan extension original dari file itu sendiri. Fungsi selanjutnya, storeAs() bertujuan untuk me-rename dimana parameter pertama berisi nama folder dan parameter kedua adalah nama baru yang akan digunakan.

Baca Juga: Mudahnya Membuat Fitur Register Dan Login Pada Laravel 5.4

Using Package

Bagi kamu yang tidak ingin repot untuk membuat fungsi selain dari yang telah disediakan oleh Laravel, maka kamu dapat menggunakan package untuk memanipulasi file. Salah satu package yang saya sukai dalam memanipulasi image adalah Intervention Image.

Install package intervention image terlebih dahulu

composer require intervention/image

Masih menggunakan form yang sama, modifikasi route dengan menggunakan class dari Intervention Image.

use Illuminate\Http\Request;
Route::post('/uploads', function(Request $request) {
    $image = $request->file('photo');
    $images = 'daengweb-' . time() . '.' . $image->getClientOriginalExtension();
    \Image::make($image)->resize(300, 200)->save(storage_path('app/uploads/' . $images));
​
    return $images;
});

Penjelasan: Konsep yang digunakan hampir sama, hanya saja dengan menggunakan package maka akan menghemat waktu dalam membuat berbagai macam fungsi yang butuhkan. Contohnya sama untuk me-resize image dengan menggunakan method resize(width, height). Tidak hanya fungsi resize yang dimiliki oleh Intervention Image, tapi masih banyak lagi seperti: kamu dapat memberikan efek opacity pada image, crop image menjadi circle, dll. Selengkapnya dapat kamu Intervention Image.

Image Validation

Jangan pernah percaya pada apa yang dilakukan user. Mungkin saja, berlandaskan pemikiran itu konsep validation ada. Laravel secara default telah menyediakan fungsi validate() yang dapat digunakan untuk mem-validasi data. Sebagai contoh, melanjutkan materi sebelumnya dimana file yang dikirim langsung di eksekusi tanpa perlu di validasi, maka pada section kali ini akan ditambahkan validasi untuk mengecek kecocokan data yang dibutuhkan oleh aplikasi yang dibuat. Modifikasi route routes/web.php menjadi seperti berikut:

use Illuminate\Http\Request;
Route::post('/uploads', function(Request $request) {
    $validation = $request->validate([
        'photo' => 'required|file|image|mimes:jpeg,png,gif,webp|max:2048'
        // multiple file uploads
        // 'photo.*' => 'required|file|image|mimes:jpeg,png,gif,webp|max:2048'
    ]);
​
    $image = $request->file('photo');
    $images = 'daengweb-' . time() . '.' . $image->getClientOriginalExtension();
    \Image::make($image)->resize(300, 200)->save(storage_path('app/uploads/' . $images));
​
    return $images;
});

Penjelasan: Ketentuan yang diharapkan adalah bahwa form upload dengan name photo tidak boleh kosong, berupa file / image dengan ekstensi jpg,png,gif,webp dan ukuran max 2048 kb. Apabila telah memenuhi ketentuan yang telah ditetapkan maka fungsi selanjutnya akan dieksekusi, jika tidak maka akan dikembalikan ke form sebelumnya.

Agar kamu tidak bingung kesalahan dari validasi yang tidak memenuhi ketentuan, maka modifikasi file resources/views/welcome.blade.php untuk menampilkan error message

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>File uploads</title>
</head>
<body>
    <form action="/uploads" enctype="multipart/form-data" method="POST">
        {{ csrf_field() }}
​
        @if ($errors->any())
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        @endif
​
        <p>
            <label for="photo">
                <input type="file" name="photo" id="photo">
            </label>
        </p>
        <button>Upload</button>
    </form>
</body>
</html>

Use External Disk

Tidak hanya local storage yang dapat digunakan sebagai tempat penyimpanan file yang telah di-upload, tapi juga external storage. Secara default, jika dilihat kedalam config/filesystems.php telah terdapat konfigurasi untuk s3 disk.

Konsep dari uploading file tidak jauh berbeda, hanya membutuhkan tambahan parameter untuk mengidentifikasi disk yang akan digunakan.

$request->file('photo')->store('photos', 's3');
​
//rename file
$path = $request->photo->storeAs('photos', 'filename.jpg', 's3');

Multiple Upload

Dalam beberapa kondisi, terkadang sebuah fitur multiple upload dibutuhkan untuk memudahkan user dalam meng-upload file yang sifatnya banyak . Maka untuk mewujudkannya tidaklah rumit, karena hanya berupa perpaduan antara upload file dan looping. Pertama-tama modifikasi file welcome.blade.php, pada bagian name untuk form upload, ubah menjadi array.

<input type="file" name="photo[]" id="photo" multiple>

Kemudian untuk proses file yang telah di-upload akan menjadi seperti ini:

use Illuminate\Http\Request;
Route::post('/uploads', function(Request $request) {
    //validasi multiple file
    $validation = $request->validate([
        'photo.*' => 'required|file|image|mimes:jpeg,png,gif,webp|max:2048'
    ]);
    
    //tampung file yang diupload
    $files = $request->file('photo');
    //define variable folder sebagai array
    $folder = [];
​
    //looping files
    foreach ($files as $file) {
        //custom name masing2 file
        $filename = 'daengweb-' . \Carbon\Carbon::now()->format('Y-m-dH:i:s') . '.' . $file->getClientOriginalExtension();
        //upload file 
        $folder[] = $file->storeAs('uploads', $filename);
    }
    return dd($folder);
});

Kesimpulan

Meng-handle, mengelola, memanipulasi sebuah file merupakan sebuah fitur yang banyak digunakan dalam sebuah aplikasi, namun perlu kehati-hatian dalam memberikan ketentuan file yang diizinkan, serta juga perlu untuk memikirkan size yang di izinkan agar ketika user sudah semakin banyak, cost untuk penyimpanannya tidak membengkak. Serta masih banyak aspek lainnya yang seiring berjalannya waktu akan ditemukan guna meningkatkan performa dari sebuah aplikasi.

Category:
Share:

Comments