Menggunakan S3 untuk Penyimpanan File di Laravel

Panduan langkah demi langkah untuk menggunakan Amazon S3 sebagai penyimpanan file dalam aplikasi Laravel, dengan konfigurasi dan implementasi praktis.
Menggunakan S3 untuk Penyimpanan File di Laravel

Installasi Library

Langkah pertama untuk menggunakan Amazon S3 di Laravel adalah menginstal library yang diperlukan, seperti aws-sdk-php melalui Composer. Ini memungkinkan integrasi Laravel dengan layanan S3 untuk penyimpanan file secara efisien.

composer require aws/aws-sdk-php

Inisialisasi S3Client

Setelah library diinstal, inisialisasi objek S3Client dengan konfigurasi kredensial AWS dan bucket S3 yang telah disiapkan. Hal ini memungkinkan aplikasi Laravel untuk terhubung dan berinteraksi dengan layanan penyimpanan S3.

S3_DRIVE_ENDPOINT=
S3_DRIVE_ACCESS_KEY=
S3_DRIVE_SECRET_KEY=
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

private $S3Client;

public function __construct()
{
    $this->S3Client = S3Client::factory([
        'version'       => 'latest',
        'region'        => 'idn',
        'endpoint'      => env('S3_DRIVE_ENDPOINT'),
        'credentials'   => [
            'key'       => env('S3_DRIVE_ACCESS_KEY'),
            'secret'    => env('S3_DRIVE_SECRET_KEY')
        ]
    ]);
}

Implementasi S3Client

Berikutnya adalah implementasi fungsi-fungsi untuk berinteraksi dengan S3 melalui S3Client. Sesuaikan nama bucket disk-public dengan yang Anda miliki.

Unggah Berkas

Cara mengunggah file dari aplikasi Laravel ke S3.

// Unggah Berkas tanpa Menimpa
public function updateAvatar(Request $request)
{
    $user = Auth::user();

    $request->validate([
        'avatar' => 'required|mimes:jpeg,png,jpg,gif,svg|max:2048',
    ], [
        'avatar.required' => 'Avatar tidak boleh kosong',
        'avatar.mimes'    => 'Hanya gambar yang diperbolehkan',
        'avatar.max'      => 'Ukuran gambar maksimal 2MB',
    ]);

    $file = $request->file('avatar');
		// $fileName = time() . '_' . $file->getClientOriginalName();
		$fileName = time() . '_' . Str::slug($user->name) . '.' . $file->getClientOriginalExtension();

    try {
        DB::beginTransaction();

        if ($request->hasFile('avatar')) {
            $this->S3Client->putObject([
                'Bucket'        => 'disk-public',
                'Key'           => $fileName,
                'ContentType'   => $file->getMimeType(),
                'SourceFile'    => $file->getPathname(),
                'ACL'           => 'public-read',
            ]);

            $avatar = $fileName;
        } else {
            $avatar = $user->avatar;
        }

        $user->update(['avatar' => $avatar]);

        DB::commit();

        return redirect()->back()->with('success', 'Berhasil memperbarui avatar');
    } catch (\Exception $e) {
        DB::rollback();
        \Log::error('Error update avatar: ' . $e->getMessage());

        return redirect()->back()->with('error', 'Terjadi kesalahan. Silakan coba lagi.');
    }
}
// Unggah Berkas dengan Menimpa
public function updateAvatar(Request $request)
{
    $user = Auth::user();

    $request->validate([
        'avatar' => 'required|mimes:jpeg,png,jpg,gif,svg|max:2048',
    ], [
        'avatar.required' => 'Avatar tidak boleh kosong',
        'avatar.mimes'    => 'Hanya gambar yang diperbolehkan',
        'avatar.max'      => 'Ukuran gambar maksimal 2MB',
    ]);

    $file = $request->file('avatar');
    // $fileName = time() . '_' . $file->getClientOriginalName();
		$fileName = time() . '_' . Str::slug($user->name) . '.' . $file->getClientOriginalExtension();

    try {
        DB::beginTransaction();

        if ($request->hasFile('avatar')) {
            $this->S3Client->deleteObject([
                'Bucket' => 'disk-public',
                'Key'    => $user->avatar,
            ]);

            $newKey = time() . '_' . $file->getClientOriginalName();
            $this->S3Client->putObject([
                'Bucket'        => 'disk-public',
                'Key'           => $fileName,
                'ContentType'   => $file->getMimeType(),
                'SourceFile'    => $file->getPathname(),
                'ACL'           => 'public-read',
            ]);

            $avatar = $fileName;
        } else {
            $avatar = $user->avatar;
        }

        $user->update(['avatar' => $avatar]);

        DB::commit();

        return redirect()->back()->with('success', 'Berhasil memperbarui avatar');
    } catch (\Exception $e) {
        DB::rollback();
        \Log::error('Error update avatar: ' . $e->getMessage());

        return redirect()->back()->with('error', 'Terjadi kesalahan. Silakan coba lagi.');
    }
}

Tampilkan Berkas

Mengakses dan menampilkan file yang tersimpan di S3.

public function index()
{
    $user = Auth::user();

    try {
        $bucketName = 'disk-public',
        $fileName   = $user->avatar ?? 'profile.webp';

        $cmd = $this->S3Client->getCommand('GetObject', [
            'Bucket' => $bucketName,
            'Key'    => $fileName,
        ]);

        $request = $this->S3Client->createPresignedRequest($cmd, '+60 minutes');

        $user->avatar = (string) $request->getUri();

        return view('setting', compact('user'));
    } catch (S3Exception $e) {
        \Log::error('Error show avatar: ' . $e->getMessage());

        return redirect()->back()->with('error', 'Terjadi kesalahan. Silakan coba lagi.');
    }
}

Hapus Berkas

Menghapus file yang sudah tidak diperlukan dari bucket S3.

public function deleteAvatar()
{
    $user = Auth::user();

    try {
        DB::beginTransaction();

        $this->S3Client->deleteObject([
            'Bucket' => 'disk-public',
            'Key'    => $user->avatar,
        ]);

        $user->update(['avatar' => null]);

        DB::commit();

        return redirect()->back()->with('success', 'Berhasil menghapus avatar');
    } catch (\Exception $e) {
        DB::rollback();
        \Log::error('Error update avatar: ' . $e->getMessage());

        return redirect()->back()->with('error', 'Terjadi kesalahan. Silakan coba lagi.');
    }
}

About the author

Zulfadli Rizal
Make it Simple but Significant!

Posting Komentar