Setiap berkas dalam aplikasi punya takdir yang berbeda: avatar pengguna boleh dilihat siapa pun, sedangkan faktur berisi alamat dan jumlah tagihan tidak boleh. Konsep disk memungkinkan kita memilah takdir itu sejak berkas pertama kali ditulis. Pada chapter sebelumnya kita telah membedah konfigurasinya; sekarang kita gunakan disk local, public, dan s3 dalam praktik, memilih disk yang tepat untuk tiap jenis berkas, lalu menjelajahi isi disk dengan method daftar berkas.

local vs public: Dua Nasib yang Berbeda #

Kedua disk bawaan ini sama-sama memakai driver local, tetapi root-nya menentukan nasib berkas:

AspekDisk localDisk public
Rootstorage/app/privatestorage/app/public
Bisa diakses via URL?Tidak — folder berada di luar public/Ya — lewat symlink public/storage
Key url di konfigurasiTidak adaAda (APP_URL/storage)
Contoh isi wajarFaktur, kontrak, backupAvatar, thumbnail, berkas yang dibagikan

Ketika kita memanggil Storage::put() tanpa menyebut disk, disk local yang terpakai karena FILESYSTEM_DISK=local. Untuk menulis ke disk lain, kita sebut namanya lewat Storage::disk():

php
use Illuminate\Support\Facades\Storage;

Storage::put('catatan-internal.txt', 'rahasia internal');            // disk local (default)
Storage::disk('public')->put('avatar-budi.png', 'isi gambar');       // disk public

Berkas pertama mendarat di storage/app/private/catatan-internal.txt dan tidak akan pernah bisa dimuat lewat browser. Berkas kedua mendarat di storage/app/public/avatar-budi.png dan siap dibagikan lewat URL setelah symlink dibuat (chapter Menampilkan File membahasnya).

Memilih Disk per Jenis Berkas #

Pemetaan disk sebaiknya diputuskan berdasarkan siapa yang berhak melihat berkas, bukan sekadar kebiasaan:

Jenis berkasDisk yang tepatAlasan
Avatar, gambar produkpublicSemua pengunjung boleh melihat
Faktur, slip gajilocal atau s3Hanya pemilik yang boleh — akses lewat controller + otorisasi
Berkas sementara (eksport sedang diproses)disk kustom tmpMudah dibersihkan massal tanpa menyentuh berkas lain
Berkas publik bervolume besars3 + CDNLebih murah dan cepat daripada disk server

Pemilihan disk di kode punya dua gaya. Gaya pertama menyebut disk per panggilan seperti contoh di atas — cocok saat aplikasi memakai banyak disk secara campuran. Gaya kedua menyimpan nama disk pada konfigurasi atau kolom database lalu memanggil Storage::disk($namaDisk); gaya ini menang ketika disk bisa berubah antar lingkungan (arsip di local saat development, di s3 saat produksi) tanpa mengubah kode. Keduanya sama-sama valid — yang penting konsisten dalam satu codebase agar pembaca kode tidak perlu menebak ke mana berkas pergi.

Konfigurasi s3 untuk Produksi #

Disk s3 pada file konfigurasi adalah templat siap pakai. Untuk mengaktifkannya, cukup isi environment variable berikut dan pasang package league/flysystem-aws-s3-v3:

dotenv
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=YOUR_AWS_KEY
AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET
AWS_DEFAULT_REGION=ap-southeast-1
AWS_BUCKET=nama-bucket

Set .env diisi seperti di atas, seluruh panggilan Storage::put() tanpa disk eksplisit otomatis menulis ke S3 — kode aplikasi tidak berubah sama sekali. Contoh pada bab ini tetap memakai disk local/public agar bisa dijalankan tanpa akun cloud dan tanpa koneksi jaringan.

Menjelajahi Isi Disk #

Disk bukan hanya tempat menulis; kita juga bisa memindai isinya. files() mengembalikan berkas pada satu level folder, allFiles() menelusuri seluruh subfolder secara rekursif, dan directories() memberi daftar folder:

php
use Illuminate\Support\Facades\Storage;

Storage::disk('public')->put('dokumen/laporan-2024.txt', 'isi laporan');
Storage::disk('public')->put('dokumen/notulen.txt', 'isi notulen');
Storage::disk('public')->put('gambar/logo.txt', 'logo proyek');

echo "allFiles public disk:\n";
print_r(Storage::disk('public')->allFiles());

echo "directories public disk:\n";
print_r(Storage::disk('public')->directories());

echo "files('dokumen') public disk:\n";
print_r(Storage::disk('public')->files('dokumen'));

Output yang Dihasilkan:

text
allFiles public disk:
Array
(
    [0] => .gitignore
    [1] => dokumen/laporan-2024.txt
    [2] => dokumen/notulen.txt
    [3] => gambar/logo.txt
)
directories public disk:
Array
(
    [0] => dokumen
    [1] => gambar
)
files('dokumen') public disk:
Array
(
    [0] => dokumen/laporan-2024.txt
    [1] => dokumen/notulen.txt
)

files() tanpa argumen hanya melaporkan berkas di root — inilah .gitignore yang memang berada di sana. allFiles() menuruni folder dokumen dan gambar sampai berkas terakhir, sementara files('dokumen') membatasi diri pada satu level folder tertentu. Method allDirectories() tersedia dengan cara kerja yang sama untuk folder. Perbedaan satu level vs rekursif ini bukan detail kosmetik: pada disk berisi puluhan ribu berkas, allFiles() adalah operasi berat yang menyusuri seluruh pohon folder, jadi untuk kebutuhan seperti “cari di folder temporer saja” selalu pilih versi non-rekursif dengan argumen folder.

Visibility: Permission Bit Saat Menulis #

Key visibility menentukan permission bit Unix yang diterapkan saat berkas ditulis: public menjadi 644 (bisa dibaca semua pengguna sistem), private menjadi 600 (hanya pemilik proses). Method setVisibility() mengubahnya setelah berkas ada:

php
use Illuminate\Support\Facades\Storage;

$disk = Storage::disk('public');
$disk->put('dokumen/notulen.txt', 'isi notulen');

$disk->setVisibility('dokumen/notulen.txt', 'private');
echo 'visibility private      : '.$disk->getVisibility('dokumen/notulen.txt')."\n";
echo 'permission bit private  : '.substr(sprintf('%o', fileperms($disk->path('dokumen/notulen.txt'))), -3)."\n";

$disk->setVisibility('dokumen/notulen.txt', 'public');
echo 'visibility public       : '.$disk->getVisibility('dokumen/notulen.txt')."\n";
echo 'permission bit public   : '.substr(sprintf('%o', fileperms($disk->path('dokumen/notulen.txt'))), -3)."\n";

Output yang Dihasilkan:

text
visibility private      : private
permission bit private  : 600
visibility public       : public
permission bit public   : 644

Kita sudah bisa menulis dan memindai disk. Namun berkas aplikasi paling sering datang bukan dari kode kita, melainkan dari pengguna yang mengunggahnya lewat form — alur lengkapnya menjadi fokus chapter berikutnya. Rujukan resmi untuk seluruh method disk tersedia di dokumentasi Filesystem .