Menu

PHP fopen(): Membuka, Membaca, Menulis File (Semua Mode)

fopen('data.txt', 'r') membuka file dan mengembalikan handle, atau false kalau gagal. Baca dari handle itu dengan fgets() atau fread(), tulis dengan fwrite(), dan tutup dengan fclose(). Mode-nya ('r', 'w', 'a', 'x', 'c', dan bentuk + dari masing-masing) menentukan apa yang bisa kamu lakukan.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

fopen('data.txt', 'r') membuka file dan mengembalikan handle, yaitu stream resource yang diterima fungsi-fungsi file lainnya sebagai argumen pertama. Baca dengan fgets() (satu baris) atau fread() (sejumlah byte), tulis dengan fwrite(), dan tutup dengan fclose(). Argumen keduanya adalah mode: 'r' untuk membaca, 'w' untuk menulis, 'a' untuk menambahkan di akhir.

Output:

Got: apple
Got: banana
Got: cherry

fopen() mengembalikan false saat tidak bisa membuka file-nya (file tidak ada dalam mode r, folder-nya tidak ada, tidak punya izin), dan PHP mencetak warning seperti:

Warning: fopen(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2

Jadi periksa false sebelum memakai handle-nya. Untuk membaca atau menulis seluruh file kecil dalam satu panggilan, file_get_contents() dan file_put_contents() lebih pendek; fopen() dipakai untuk file yang dibaca sepotong demi sepotong atau dibiarkan tetap terbuka.

Mode fopen

ModeBacaTulisKalau file-nya adaKalau belum adaMulai dari
ryatidakmembukanyagagalawal
r+yayamembukanya, isinya tetapgagalawal
wtidakyamengosongkannyamembuatnyaawal
w+yayamengosongkannyamembuatnyaawal
atidakyaisinya tetapmembuatnyaakhir, setiap tulisan ditambahkan di akhir
a+yayaisinya tetapmembuatnyaakhir, setiap tulisan ditambahkan di akhir
xtidakyagagalmembuatnyaawal
x+yayagagalmembuatnyaawal
ctidakyaisinya tetapmembuatnyaawal
c+yayaisinya tetapmembuatnyaawal

Dua baris ini sering mengejutkan. r+ menimpa byte yang sudah ada di tempatnya, tanpa menyisipkan, dan a+ selalu menulis di akhir, bahkan setelah kamu memindahkan pointer dengan fseek() (memindahkannya hanya berpengaruh pada pembacaan):

Output:

Xbc
Xbc
Xbc
end

Di Windows, kamu mungkin melihat 'rb' atau 'wb': flag b berarti biner dan mencegah Windows menerjemahkan akhir baris. Flag ini tidak berpengaruh apa-apa di Linux dan macOS, jadi menambahkannya tidak berbahaya dan portabel.

Membaca file baris per baris dengan fgets()

fgets() mengembalikan baris berikutnya termasuk \n-nya, dan false di akhir file. Karena hanya satu baris yang ada di memori setiap saat, loop ini bisa menangani file log sebesar apa pun, dan kamu bisa berhenti lebih awal dengan break:

Output:

2 errors in 5 lines
line 2: database timeout
line 4: disk full

Bandingkan dengan false memakai !==, jangan memakai while ($line = fgets($fh)) biasa: baris yang hanya berisi "0" tanpa baris baru (baris terakhir sebuah file bisa seperti itu) bernilai falsy dan akan menghentikan loop terlalu cepat.

fwrite() menulis string di posisi saat ini dan mengembalikan jumlah byte yang ditulis, atau false kalau gagal. fputs() adalah fungsi yang sama dengan nama lain. Buka dengan 'a' untuk menambahkan ke akhir file tanpa menyentuh isi yang sudah ada:

Output:

wrote 12 bytes
wrote 13 bytes
wrote 15 bytes
visit /home
visit /about
visit /contact
visit /home

PHP_EOL adalah akhir baris dari sistem tempat PHP berjalan (\n di Linux dan macOS, \r\n di Windows). Untuk file yang dibaca program lain, pilih salah satu secara eksplisit, biasanya "\n".

Membaca dan menulis file CSV dengan fgetcsv() dan fputcsv()

fputcsv() menulis array sebagai satu baris CSV dan memberi kutip pada field yang mengandung koma, tanda kutip, atau baris baru. fgetcsv() membaca satu baris kembali sebagai array. Berikan pemisah, karakter pembungkus, dan karakter escape kosong secara eksplisit: itu menghasilkan CSV standar, dan PHP 8.4 mencetak deprecation notice kalau argumen escape tidak ditulis.

Output:

name,city,note
Ada,London,"likes ""math"", a lot"
Linus,Helsinki,kernel

Ada lives in London: likes "math", a lot
Linus lives in Helsinki: kernel

Memecah baris dengan explode(',', $line) langsung rusak begitu sebuah field mengandung koma; fgetcsv() menangani kutipnya untukmu. Untuk file yang dipisahkan titik koma (umum pada hasil ekspor Excel di Eropa), berikan ';' sebagai pemisah.

Berpindah posisi di file dengan fseek(), ftell(), dan rewind()

File yang terbuka punya posisi. Pembacaan dan penulisan dimulai dari sana lalu memajukan posisinya. ftell() memberi tahu di mana posisinya, fseek() memindahkannya ke offset byte tertentu, dan rewind() kembali ke awal. Dengan w+, kamu bisa menulis file lalu membacanya kembali lewat handle yang sama:

Output:

11
world
hello world

Mengunci file dengan flock()

Dua request yang membaca sebuah penghitung, menambah satu, lalu menulisnya kembali pada saat bersamaan bisa sama-sama membaca 41 dan sama-sama menulis 42. flock() dengan LOCK_EX membuat request kedua menunggu sampai request pertama melepas lock-nya. Mode c+ adalah yang tepat di sini: mode ini membuat file kalau perlu dan, tidak seperti w+, tidak mengosongkannya sebelum kamu memegang lock.

Output:

Visitor number 1
Visitor number 2
Visitor number 3

Lock bersifat advisory: hanya menghentikan kode lain yang juga memanggil flock(). Untuk menambahkan satu baris, file_put_contents($path, $line, FILE_APPEND | LOCK_EX) melakukan hal yang sama dalam satu panggilan.

Kesalahan umum: while (!feof($fh))

Banyak tutorial lama memakai loop dengan feof(). Fungsi ini baru mengembalikan true setelah sebuah pembacaan sudah mencapai akhir, jadi loop-nya berjalan sekali lebih banyak daripada jumlah barisnya dan fgets() terakhir mengembalikan false:

Output:

string(2) "a
"
string(2) "b
"
string(2) "c
"
bool(false)
4 rounds for 3 lines

false tambahan itu menjadi baris kosong di laporan atau elemen kosong di array. Buat loop berdasarkan pembacaannya sendiri, while (($line = fgets($fh)) !== false), seperti setiap contoh lain di halaman ini.

Pertanyaan yang sering diajukan

Apa saja mode fopen di PHP?

r untuk membaca, w untuk menulis setelah mengosongkan file, a untuk menulis di akhir, x untuk membuat file baru dan gagal kalau file itu sudah ada, dan c untuk menulis tanpa mengosongkannya. Menambahkan + (r+, w+, a+, x+, c+) mengizinkan membaca dan menulis sekaligus. Setiap mode kecuali r dan r+ membuat file-nya kalau belum ada.

Apa bedanya w dan a di fopen?

w mengosongkan file begitu dibuka dan menulis dari awal. a mempertahankan isinya, dan setiap fwrite() masuk ke akhir file, bahkan setelah fseek(), sehingga inilah mode untuk file log.

Bagaimana cara membaca file CSV di PHP?

Buka dengan fopen($path, 'r') lalu panggil fgetcsv() di dalam loop: while (($row = fgetcsv($fh, null, ',', '"', '')) !== false) { ... }. Setiap panggilan mengembalikan satu baris sebagai array berisi field-field, dengan tanda kutip dan koma di dalam field sudah ditangani untukmu.

Apakah perlu memanggil fclose di PHP?

PHP menutup setiap file yang masih terbuka saat script selesai, jadi script pendek tetap berjalan tanpanya. Tetap panggil fclose() begitu kamu selesai: fungsi ini mengirim tulisan yang masih di buffer, melepas lock yang diambil dengan flock(), dan mencegah script yang berjalan lama kehabisan file handle.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai