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
| Mode | Baca | Tulis | Kalau file-nya ada | Kalau belum ada | Mulai dari |
|---|---|---|---|---|---|
r | ya | tidak | membukanya | gagal | awal |
r+ | ya | ya | membukanya, isinya tetap | gagal | awal |
w | tidak | ya | mengosongkannya | membuatnya | awal |
w+ | ya | ya | mengosongkannya | membuatnya | awal |
a | tidak | ya | isinya tetap | membuatnya | akhir, setiap tulisan ditambahkan di akhir |
a+ | ya | ya | isinya tetap | membuatnya | akhir, setiap tulisan ditambahkan di akhir |
x | tidak | ya | gagal | membuatnya | awal |
x+ | ya | ya | gagal | membuatnya | awal |
c | tidak | ya | isinya tetap | membuatnya | awal |
c+ | ya | ya | isinya tetap | membuatnya | awal |
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.
Menulis dan menambahkan dengan fwrite()
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.