PHP Dosya Okuma

PHP ile dosya okuma işlemlerini öğrenin.

PHP'de dosya okuma, web uygulamalarının önemli bir parçasıdır. Log dosyalarını okumak, yapılandırma dosyalarını işlemek, kullanıcı tarafından yüklenen verileri okumak veya basit metin dosyalarını görüntülemek gibi birçok senaryoda kullanılır. PHP, dosya okuma için farklı ihtiyaçlara yönelik çeşitli fonksiyonlar ve yöntemler sunar. İşte başlıca yöntemler: --- ### 1. `file_get_contents()` - En Basit ve Hızlı Yöntem Bu fonksiyon, bir dosyanın **tüm içeriğini tek bir string olarak** okur ve döndürür. Küçük ve orta boyutlu dosyalar için oldukça kullanışlıdır. **Kullanım Amacı:** * Küçük metin dosyalarını okumak. * Bir URL'deki içeriği (örn. API yanıtları) almak. * Yapılandırma dosyalarını tek seferde okumak. **Sözdizimi:** ```php string file_get_contents ( string $filename [, bool $use_include_path = FALSE [, resource $context = NULL [, int $offset = 0 [, int $maxlen ]]]] ) ``` **Örnek:** ```php <?php $dosyaAdi = 'ornek.txt'; // Dosyanın varlığını ve okunabilirliğini kontrol edin if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { $icerik = file_get_contents($dosyaAdi); if ($icerik !== false) { echo "Dosya İçeriği:\n" . $icerik; } else { echo "Dosya içeriği okunurken bir hata oluştu."; } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` **Avantajları:** * Kullanımı çok kolay ve hızlıdır. * Tek satırda tüm dosya içeriğini alır. **Dezavantajları:** * **Çok büyük dosyalar için uygun değildir.** Tüm dosya içeriğini belleğe yüklediği için bellek tüketimi sorunu yaratabilir. * Dosyanın tamamını okumadan işlem yapma imkanı sunmaz. --- ### 2. `file()` - Satır Satır Okuyup Diziye Aktarma Bu fonksiyon, bir dosyanın her satırını okur ve her satırı bir dizi elemanı olarak içeren bir dizi döndürür. Satır sonu karakterleri (`\n`, `\r\n`) genellikle dizi elemanlarında kalır. **Kullanım Amacı:** * Satır tabanlı metin dosyalarını (örn. log dosyaları, CSV benzeri dosyalar) işlemek. * Her satır üzerinde döngü yaparak işlem yapmak. **Sözdizimi:** ```php array file ( string $filename [, int $flags = 0 [, resource $context = NULL ]] ) ``` **Örnek:** ```php <?php $dosyaAdi = 'ornek.txt'; if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { // FILE_IGNORE_NEW_LINES: Satır sonu karakterlerini kaldırmaz // FILE_SKIP_EMPTY_LINES: Boş satırları atlar $satirlar = file($dosyaAdi, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($satirlar !== false) { echo "Dosya Satırları:\n"; foreach ($satirlar as $numara => $satir) { echo ($numara + 1) . ": " . $satir . "\n"; } } else { echo "Dosya satırları okunurken bir hata oluştu."; } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` **Avantajları:** * Dosyayı satır bazında kolayca işleme imkanı sunar. * `file_get_contents()`'e göre biraz daha fazla kontrol sağlar. **Dezavantajları:** * Yine de **çok büyük dosyalar için bellek tüketimi** sorunu yaşatabilir, çünkü tüm satırları bellekte bir dizi olarak tutar. --- ### 3. `readfile()` - Doğrudan Çıkışa Yazma Bu fonksiyon, bir dosyanın içeriğini doğrudan tarayıcıya (veya belirtilen bir çıktı akışına) gönderir. Dosya içeriğini bir değişkene atamaz, bu nedenle özellikle dosya indirme veya statik içerik sunma durumlarında bellek dostudur. **Kullanım Amacı:** * Kullanıcının bir dosyayı indirmesini sağlamak. * Büyük statik dosyaları (HTML, TXT, resimler vb.) doğrudan tarayıcıya göndermek. **Sözdizimi:** ```php int readfile ( string $filename [, bool $use_include_path = FALSE [, resource $context = NULL ]] ) ``` **Örnek:** ```php <?php $dosyaAdi = 'ornek.txt'; if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { // İndirme başlatmak için HTTP başlıkları // header('Content-Description: File Transfer'); // header('Content-Type: application/octet-stream'); // header('Content-Disposition: attachment; filename="'.basename($dosyaAdi).'"'); // header('Expires: 0'); // header('Cache-Control: must-revalidate'); // header('Pragma: public'); // header('Content-Length: ' . filesize($dosyaAdi)); // Dosya içeriğini doğrudan çıktıya yaz $byteSayisi = readfile($dosyaAdi); if ($byteSayisi !== false) { echo "\n" . $byteSayisi . " byte okundu ve çıktıya yazıldı."; // Bu satır indirme durumunda görünmez } else { echo "Dosya okunurken bir hata oluştu."; } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` **Avantajları:** * **Çok büyük dosyalar için bellek verimlidir**, çünkü içeriği bellekte tutmaz, doğrudan çıktıya akıtır. * Özellikle dosya indirme işlemleri için idealdir. **Dezavantajları:** * Dosya içeriğini bir değişkende işleme imkanı sunmaz. Sadece çıktıya yazar. --- ### 4. `fopen()`, `fread()`, `fgets()`, `fgetcsv()`, `fclose()` - Düşük Seviyeli Kontrol Bu fonksiyonlar, dosya işlemlerinde en düşük seviyeli ve en esnek kontrolü sağlar. Bir dosyayı açar, istediğiniz boyutta veya satır satır okur ve işiniz bittiğinde kapatır. Özellikle **çok büyük dosyaları parçalar halinde okumak** için idealdirler. #### 4.1. `fopen()` ve `fread()` (Parça Parça Okuma) Bu yöntem, dosyayı ikili (binary) modda açıp belirli boyutlardaki parçalar halinde okumanızı sağlar. **Kullanım Amacı:** * Çok büyük dosyaların içeriğini belleğe yüklemeden işlemek. * İkili dosyaları (resimler, videolar vb.) okumak. * Custom bir protokol veya formatı okumak. **Sözdizimi:** ```php resource fopen ( string $filename , string $mode [, bool $use_include_path = FALSE [, resource $context = NULL ]] ) string fread ( resource $handle , int $length ) bool fclose ( resource $handle ) ``` **Örnek:** ```php <?php $dosyaAdi = 'ornek.txt'; $parcaBoyutu = 1024; // 1 KB if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { // Dosyayı okuma modunda aç $dosya = fopen($dosyaAdi, 'rb'); // 'rb' -> binary okuma modu if ($dosya) { echo "Dosyadan parça parça okuma:\n"; while (!feof($dosya)) { // Dosya sonuna kadar oku $parca = fread($dosya, $parcaBoyutu); if ($parca !== false) { echo $parca; // Her bir parçayı yazdır } else { echo "Parça okunurken hata oluştu."; break; } } fclose($dosya); // Dosyayı kapat } else { echo "Dosya açılamadı."; } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` #### 4.2. `fopen()` ve `fgets()` (Satır Satır Okuma) Bu yöntem, dosyayı satır satır okumanızı sağlar, ancak `file()` fonksiyonunun aksine tüm satırları bellekte bir dizi olarak tutmaz. **Kullanım Amacı:** * Çok büyük log dosyalarını veya metin dosyalarını satır satır işlemek. * Her satırı okurken belirli koşullara göre işlem yapmak. **Sözdizimi:** ```php string fgets ( resource $handle [, int $length ] ) ``` **Örnek:** ```php <?php $dosyaAdi = 'ornek.txt'; if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { $dosya = fopen($dosyaAdi, 'r'); // 'r' -> metin okuma modu if ($dosya) { echo "Dosyadan satır satır okuma:\n"; $satirNumarasi = 1; while (($satir = fgets($dosya)) !== false) { echo ($satirNumarasi++) . ": " . $satir; // Satır sonu karakteri genellikle satırda bulunur } fclose($dosya); } else { echo "Dosya açılamadı."; } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` #### 4.3. `fopen()` ve `fgetcsv()` (CSV Okuma) Bu fonksiyon, bir CSV (Comma Separated Values) dosyasını açıp her satırı ayrıştırılmış bir dizi olarak okumanızı sağlar. **Kullanım Amacı:** * CSV formatındaki verileri okumak ve işlemek. **Sözdizimi:** ```php array|false fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = "\"" [, string $escape = "\\" ]]]] ) ``` **Örnek:** ```php <?php // ornek.csv içeriği: // Ad,Soyad,Yaş // Ali,Yılmaz,30 // Ayşe,Demir,25 // Mehmet,Kara,40 $dosyaAdi = 'ornek.csv'; if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { $dosya = fopen($dosyaAdi, 'r'); if ($dosya) { echo "CSV Dosyası İçeriği:\n"; $satirNumarasi = 0; while (($veri = fgetcsv($dosya, 1000, ',')) !== false) { // 1000: max satır uzunluğu, ',' ayırıcı $satirNumarasi++; if ($satirNumarasi == 1) { // Başlık satırını atla veya özel işle echo "Başlıklar: " . implode(" | ", $veri) . "\n"; continue; } echo "Kişi " . ($satirNumarasi - 1) . ": Ad: " . $veri[0] . ", Soyad: " . $veri[1] . ", Yaş: " . $veri[2] . "\n"; } fclose($dosya); } else { echo "Dosya açılamadı."; } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` **Avantajları (Düşük Seviyeli Fonksiyonların):** * **Çok büyük dosyalar için en iyi bellek performansı** sağlar, çünkü tüm dosya içeriğini veya tüm satırları bellekte tutmaz. * Okuma üzerinde tam kontrol sağlar (kaç byte okunacağı, satır satır mı okunacağı vb.). * Ağ kaynakları veya diğer akışlar üzerinde de çalışabilir. **Dezavantajları:** * `file_get_contents()` gibi basit yöntemlere göre daha fazla kod yazmayı gerektirir. * `fopen()` ile açılan kaynakların `fclose()` ile mutlaka kapatılması gerekir, aksi takdirde kaynak sızıntıları olabilir. --- ### 5. `SplFileObject` - Nesne Yönelimli Yaklaşım PHP'nin Standard PHP Library (SPL) içindeki `SplFileObject` sınıfı, dosya işlemleri için nesne yönelimli bir arayüz sunar. `fopen()`, `fgets()`, `fgetcsv()` gibi fonksiyonların işlevselliğini bir nesne çatısı altında birleştirir ve Iterator arayüzünü uyguladığı için `foreach` döngüsüyle kolayca kullanılabilir. **Kullanım Amacı:** * Nesne yönelimli kod yazmayı tercih edenler için. * Büyük dosyaları satır satır veya CSV olarak işlerken daha temiz ve okunaklı bir kod arayanlar. * Daha fazla esneklik ve metod zincirleme gibi OOP özelliklerinden yararlanmak isteyenler. **Örnek:** ```php <?php $dosyaAdi = 'ornek.txt'; if (file_exists($dosyaAdi) && is_readable($dosyaAdi)) { try { $file = new SplFileObject($dosyaAdi, 'r'); // 'r' okuma modu $file->setFlags(SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE); // Satır sonlarını kaldır, boş satırları atla echo "SplFileObject ile okuma (metin):\n"; $satirNumarasi = 1; foreach ($file as $satir) { echo ($satirNumarasi++) . ": " . $satir . "\n"; } // CSV okuma için farklı bir örnek $csvDosyaAdi = 'ornek.csv'; if (file_exists($csvDosyaAdi) && is_readable($csvDosyaAdi)) { $csvFile = new SplFileObject($csvDosyaAdi, 'r'); $csvFile->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::READ_AHEAD); $csvFile->setCsvControl(',', '"', '\\'); // Ayırıcı, kapsayıcı, kaçış karakteri echo "\nSplFileObject ile okuma (CSV):\n"; $satirNumarasi = 0; foreach ($csvFile as $row) { $satirNumarasi++; if ($satirNumarasi == 1) { echo "Başlıklar: " . implode(" | ", $row) . "\n"; continue; } if (is_array($row) && count($row) >= 3) { echo "Kişi " . ($satirNumarasi - 1) . ": Ad: " . $row[0] . ", Soyad: " . $row[1] . ", Yaş: " . $row[2] . "\n"; } } } else { echo "Hata: CSV dosyası bulunamadı veya okunabilir değil."; } } catch (RuntimeException $e) { echo "Dosya hatası: " . $e->getMessage(); } } else { echo "Hata: Dosya bulunamadı veya okunabilir değil."; } ?> ``` **Avantajları:** * Nesne yönelimli bir arayüz sunar, bu da kodu daha organize ve okunabilir yapar. * `foreach` döngüsü ile kolayca iterate edilebilir. * `setFlags()` ve `setCsvControl()` gibi metodlarla ek özellikler ve yapılandırma imkanı sunar. * Bellek verimlidir, `fopen`/`fgets` gibi çalışır. **Dezavantajları:** * Daha basit dosya okuma işlemleri için biraz fazla karmaşık gelebilir. --- ### Güvenlik ve Hata Yönetimi İpuçları: 1. **Her Zaman Kontrol Edin:** Bir dosyayı okumaya çalışmadan önce `file_exists()` ve `is_readable()` gibi fonksiyonlarla dosyanın varlığını ve okunabilirliğini kontrol edin. 2. **Kullanıcı Girişini Temizleyin:** Eğer dosya adı kullanıcıdan geliyorsa, yol değiştirme (path traversal) saldırılarını önlemek için dosya adını mutlaka temizleyin ve doğrulayın (örn. `basename()`, `realpath()`). 3. **Hata Kontrolü:** Dosya okuma fonksiyonları `false` döndürebilir. Her zaman dönüş değerlerini kontrol edin. `fopen()` başarısız olursa `false` döndürür; `file_get_contents()` da aynı şekilde. 4. **Kaynakları Kapatın:** `fopen()` ile açtığınız tüm dosya tanıtıcılarını (`resource`) işiniz bittiğinde `fclose()` ile kapatmayı unutmayın. `SplFileObject` gibi nesneler, PHP'nin çöp toplayıcısı tarafından otomatik olarak kapatılsa da, erken kapatmak iyi bir uygulama olabilir. 5. **İzinler:** PHP betiğinin çalıştığı kullanıcının (genellikle web sunucusu kullanıcısı, örn. `www-data` veya `apache`) dosyayı okuma iznine sahip olduğundan emin olun. --- ### Hangi Yöntem Ne Zaman Kullanılmalı? * **`file_get_contents()`:** En küçük ve orta boyutlu dosyaları (birkaç MB'a kadar) okumak için en kolay ve hızlı yöntemdir. Özellikle URL'lerden veri çekerken çok kullanışlıdır. * **`file()`:** Satır bazında işlem yapmanız gereken, yine küçük ve orta boyutlu dosyalar için uygundur. Tüm satırları bir diziye yüklediği için belleğe dikkat edin. * **`readfile()`:** Dosya içeriğini bir değişkene almak yerine doğrudan tarayıcıya (veya çıktıya) göndermeniz gerektiğinde, özellikle büyük dosyalar için bellek açısından en verimli seçenektir. * **`fopen()` + `fread()`/`fgets()`/`fgetcsv()`:** Çok büyük dosyaları (gigabaytlarca) işlerken, belleği tüketmeden parça parça veya satır satır okumanız gerektiğinde en iyi seçimdir. CSV dosyaları için `fgetcsv()` özel olarak kullanışlıdır. * **`SplFileObject`:** Nesne yönelimli bir yaklaşımı tercih ediyor ve büyük dosyaları satır satır veya CSV olarak işlerken daha modern ve esnek bir yapı arıyorsanız idealdir. Her yöntemin kendine özgü avantajları ve dezavantajları vardır. Uygulamanızın gereksinimlerine (dosya boyutu, okunma şekli, bellek kısıtlamaları vb.) göre en uygun yöntemi seçmelisiniz.
Son Paylaşımlar
Kategoriler