fopen('data.txt', 'r') bir dosyayı açar ve bir tanıtıcı, yani diğer dosya fonksiyonlarının ilk argüman olarak aldığı bir akış kaynağı döndürür. fgets() (bir satır) veya fread() (belirli sayıda bayt) ile okuyun, fwrite() ile yazın ve fclose() ile kapatın. İkinci argüman moddur: okumak için 'r', yazmak için 'w', eklemek için 'a'.
Çıktı:
Got: apple
Got: banana
Got: cherry
fopen() dosyayı açamadığında (dosya r modunda yok, bir klasör eksik, izin yok) false döndürür ve PHP şuna benzer bir uyarı yazdırır:
Warning: fopen(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2
Bu yüzden tanıtıcıyı kullanmadan önce false kontrolü yapın. Küçük bir dosyanın tamamını tek çağrıda okumak veya yazmak için file_get_contents() ve file_put_contents() daha kısadır; fopen() parça parça okuduğunuz veya açık tuttuğunuz dosyalar içindir.
fopen modları
| Mod | Okuma | Yazma | Dosya varsa | Yoksa | Başlangıç |
|---|---|---|---|---|---|
r | evet | hayır | açar | başarısız olur | baş |
r+ | evet | evet | açar, içeriği korur | başarısız olur | baş |
w | hayır | evet | boşaltır | oluşturur | baş |
w+ | evet | evet | boşaltır | oluşturur | baş |
a | hayır | evet | içeriği korur | oluşturur | son, her yazma sona ekler |
a+ | evet | evet | içeriği korur | oluşturur | son, her yazma sona ekler |
x | hayır | evet | başarısız olur | oluşturur | baş |
x+ | evet | evet | başarısız olur | oluşturur | baş |
c | hayır | evet | içeriği korur | oluşturur | baş |
c+ | evet | evet | içeriği korur | oluşturur | baş |
İki satır insanları şaşırtır. r+ araya eklemeden var olan baytların üzerine yerinde yazar ve a+ işaretçiyi fseek() ile hareket ettirdikten sonra bile her zaman sona yazar (onu hareket ettirmek yalnızca okumaları etkiler):
Çıktı:
Xbc
Xbc
Xbc
end
Windows'ta 'rb' veya 'wb' görebilirsiniz: b bayrağı ikili (binary) demektir ve Windows'un satır sonlarını çevirmesini önler. Linux ve macOS'ta hiçbir şey yapmaz, bu yüzden eklemek zararsızdır ve taşınabilirdir.
fgets() ile bir dosyayı satır satır okuma
fgets() bir sonraki satırı \n dahil olarak, dosyanın sonunda ise false döndürür. Bellekte her seferinde yalnızca bir satır olduğu için bu döngü her boyuttaki bir log dosyasını işler ve break ile erken durabilirsiniz:
Çıktı:
2 errors in 5 lines
line 2: database timeout
line 4: disk full
Düz bir while ($line = fgets($fh)) ile değil, !== kullanarak false ile karşılaştırın: yalnızca "0" içeren ve yeni satırı olmayan bir satır (bir dosyanın son satırı böyle olabilir) falsy'dir ve döngüyü erken bitirirdi.
fwrite() ile yazma ve ekleme
fwrite() geçerli konuma bir dizge yazar ve yazılan bayt sayısını, başarısızlıkta false döndürür. fputs() başka bir addaki aynı fonksiyondur. Oradakine dokunmadan bir dosyanın sonuna eklemek için 'a' ile açın:
Çıktı:
wrote 12 bytes
wrote 13 bytes
wrote 15 bytes
visit /home
visit /about
visit /contact
visit /home
PHP_EOL PHP'nin çalıştığı sistemin satır sonudur (Linux ve macOS'ta \n, Windows'ta \r\n). Başka programların okuduğu dosyalar için açıkça birini seçin, genellikle "\n".
fgetcsv() ve fputcsv() ile CSV dosyalarını okuma ve yazma
fputcsv() bir diziyi tek bir CSV satırı olarak yazar ve virgül, tırnak veya yeni satır içeren alanları tırnak içine alır. fgetcsv() bir satırı geri bir dizi olarak okur. Ayırıcıyı, çevreleyiciyi ve boş bir kaçış karakterini açıkça verin: bu standart CSV verir ve kaçış argümanı yazılmadığında PHP 8.4 bir kullanımdan kaldırma bildirimi yazdırır.
Çıktı:
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
Satırları explode(',', $line) ile bölmek bir alan virgül içerdiği anda bozulur; fgetcsv() tırnaklamayı sizin için ele alır. Noktalı virgülle ayrılmış bir dosya için (Avrupa'daki Excel dışa aktarımlarında yaygındır) ayırıcı olarak ';' verin.
fseek(), ftell() ve rewind() ile bir dosyada dolaşma
Açık bir dosyanın bir konumu vardır. Okumalar ve yazmalar oradan başlar ve onu ileri taşır. ftell() nerede olduğunu söyler, fseek() onu bir bayt konumuna taşır ve rewind() başa döner. w+ ile bir dosya yazıp aynı tanıtıcı üzerinden geri okuyabilirsiniz:
Çıktı:
11
world
hello world
flock() ile bir dosyayı kilitleme
Aynı anda bir sayacı okuyup bir ekleyen ve geri yazan iki istek ikisi de 41 okuyup ikisi de 42 yazabilir. LOCK_EX ile flock() ikincisinin, ilki kilidi serbest bırakana kadar beklemesini sağlar. Burada doğru mod c+ olur: gerekirse dosyayı oluşturur ve w+ aksine kilidi almadan önce onu boşaltmaz.
Çıktı:
Visitor number 1
Visitor number 2
Visitor number 3
Kilitler tavsiye niteliğindedir: yalnızca flock() çağıran diğer kodu durdurur. Tek bir satır eklemek için file_put_contents($path, $line, FILE_APPEND | LOCK_EX) aynısını tek çağrıda yapar.
Sık yapılan hata: while (!feof($fh))
Birçok eski eğitim feof() ile döngü kurar. O, ancak bir okuma sona zaten çarptıktan sonra true döndürür, bu yüzden döngü satır sayısından bir fazla çalışır ve son fgets() false döndürür:
Çıktı:
string(2) "a
"
string(2) "b
"
string(2) "c
"
bool(false)
4 rounds for 3 lines
O fazladan false bir raporda boş bir satıra ya da bir dizide boş bir elemana dönüşür. Bu sayfadaki diğer her örneğin yaptığı gibi döngüyü okumanın kendisine kurun: while (($line = fgets($fh)) !== false).
Sıkça Sorulan Sorular
PHP'de fopen modları nelerdir?
r okur, w dosyayı boşalttıktan sonra yazar, a sona yazar, x yeni bir dosya oluşturur ve dosya varsa başarısız olur, c ise boşaltmadan yazar. + eklemek (r+, w+, a+, x+, c+) hem okumaya hem yazmaya izin verir. r ve r+ dışındaki her mod dosya eksikse onu oluşturur.
fopen içinde w ile a arasındaki fark nedir?
w dosyayı açılır açılmaz boşaltır ve baştan yazar. a içeriği korur ve her fwrite() fseek() sonrasında bile dosyanın sonuna gider; bu da onu log dosyaları için mod yapar.
PHP'de bir CSV dosyasını nasıl okurum?
Onu fopen($path, 'r') ile açın ve bir döngüde fgetcsv() çağırın: while (($row = fgetcsv($fh, null, ',', '"', '')) !== false) { ... }. Her çağrı bir satırı alanlardan oluşan bir dizi olarak döndürür; tırnaklar ve gömülü virgüller sizin için ele alınır.
PHP'de fclose çağırmam gerekir mi?
PHP betik bittiğinde her açık dosyayı kapatır, bu yüzden kısa bir betik onsuz da çalışır. Yine de işiniz biter bitmez fclose() çağırın: arabelleğe alınmış yazmaları boşaltır, flock() ile alınan kilitleri serbest bırakır ve uzun süre çalışan bir betiğin dosya tanıtıcılarının tükenmesini önler.