
PHP Döngüleri: for, while, foreach ve Akış Kontrolü
Döngü, bir kod bloğunu koşul sağlandığı sürece tekrar çalıştırır. PHP dört döngü yapısı sunar ve aralarındaki fark tekrar sayısının önceden bilinip bilinmemesine dayanır. Yanlış yapının seçilmesi çoğu zaman çalışan ama gereksiz yere karmaşık koda yol açar.
for: tekrar sayısı belliyse
Sayacın başlangıcı, bitiş koşulu ve artış miktarı tek satırda tanımlanır. Tekrar sayısının önceden bilindiği durumlar için uygundur:
for ($i = 1; $i <= 5; $i++) {
echo "Satır {$i}" . PHP_EOL;
}Bitiş koşulunda fonksiyon çağrısı yapmaktan kaçınmak gerekir. $i < count($dizi) yazıldığında count her adımda yeniden çalışır; değer döngü öncesinde bir değişkene alınmalıdır.
$adet = count($dizi);
for ($i = 0; $i < $adet; $i++) {
islem($dizi[$i]);
}Sayacın döngü dışında da gerekli olduğu durumlar dışında, indeksle gezinmek yerine foreach tercih edilir. İndeks hatası, dizinin sonunu bir eleman aşmak gibi klasik sorunların büyük kısmı bu tercihle ortadan kalkar.
while ve do-while: koşula bağlı tekrar
while, koşulu her tekrardan önce kontrol eder. Koşul en baştan yanlışsa gövde hiç çalışmaz. do-while ise gövdeyi önce çalıştırır, koşulu sonra bakar; yani en az bir kez çalışması garanti edilir:
$satir = fgets($dosya);
while ($satir !== false) {
islem(trim($satir));
$satir = fgets($dosya);
}
$deneme = 0;
do {
$sonuc = baglan();
$deneme++;
} while ($sonuc === false && $deneme < 3);while kullanılan yerlerde döngüyü sonlandıracak değişikliğin gövde içinde mutlaka yapılması gerekir. Aksi halde sonsuz döngü oluşur ve betik zaman aşımına kadar çalışır.
foreach: diziler ve nesneler
Dizilerde tercih edilecek yapı foreach'tir. İndeks yönetimi gerektirmez ve ilişkisel dizilerde anahtarı da verir:
$fiyatlar = ['kalem' => 12.5, 'defter' => 34.0];
foreach ($fiyatlar as $urun => $fiyat) {
printf('%s: %.2f TL%s', $urun, $fiyat, PHP_EOL);
}Dizinin elemanlarını döngü içinde değiştirmek gerekiyorsa referans kullanılır. Referansla döngüden sonra değişkenin unset edilmemesi, sonraki döngülerde son elemanın bozulmasına yol açan klasik bir hatadır:
foreach ($sayilar as &$sayi) {
$sayi *= 2;
}
unset($sayi);break ve continue ile akış kontrolü
break döngüyü tamamen sonlandırır, continue yalnızca o adımı atlar. İç içe döngülerde her ikisi de sayı parametresi alarak birden fazla seviyeyi etkileyebilir:
foreach ($siparisler as $siparis) {
if ($siparis['durum'] === 'iptal') {
continue;
}
if ($siparis['tutar'] > $limit) {
break;
}
isle($siparis);
}İç içe döngüler ve maliyet
İç içe iki döngü, eleman sayısının karesiyle orantılı işlem üretir. Bin elemanlı iki dizi karşılaştırıldığında bir milyon adım oluşur. Bu tür karşılaştırmalar için dizinin anahtar üzerinden indekslenmesi çok daha hızlı sonuç verir:
// yavaş: her eleman için tüm diziyi tara
foreach ($a as $x) {
if (in_array($x, $b, true)) { /* ... */ }
}
// hızlı: anahtar araması sabit zamanlı
$indeks = array_flip($b);
foreach ($a as $x) {
if (isset($indeks[$x])) { /* ... */ }
}Döngü yerine dizi fonksiyonu
Her tekrar eden iş döngü gerektirmez. Filtreleme, dönüştürme ve toplama işlemleri için hazır dizi fonksiyonları hem daha kısa hem de niyeti daha açık ifade eder. Aşağıdaki iki blok aynı sonucu üretir:
// döngüyle
$aktifler = [];
foreach ($kullanicilar as $k) {
if ($k['aktif']) {
$aktifler[] = $k;
}
}
// dizi fonksiyonuyla
$aktifler = array_filter($kullanicilar, fn(array $k): bool => $k['aktif']);Döngü, işin içinde koşullu erken çıkış ya da birden fazla yan etki varsa hâlâ daha okunur kalır. Seçim, kodun kısalığından çok neyi anlattığına göre yapılmalıdır.
Sonsuz döngü ve zaman aşımı
Sonsuz döngü genellikle koşulu değiştiren satırın unutulmasından ya da koşulun hiç sağlanamayacak biçimde yazılmasından kaynaklanır. Web isteğinde betik max_execution_time sınırına kadar çalışır ve sonra kesilir; komut satırında ise bu sınır varsayılan olarak yoktur, süreç elle durdurulana kadar devam eder.
Dış kaynağa bağlı bekleyen döngülerde güvenlik payı bırakmak gerekir. Deneme sayısına üst sınır koymak, hem sonsuz bekleyişi hem de karşı tarafa gereksiz yük binmesini engeller:
$deneme = 0;
$enFazla = 5;
while ($deneme < $enFazla) {
$sonuc = istekGonder();
if ($sonuc !== false) {
break;
}
$deneme++;
sleep(2 ** $deneme);
}Kontrol listesi
- Tekrar sayısı biliniyorsa for, dizide geziliyorsa foreach kullanılır.
- Döngü koşulunda fonksiyon çağrısı bırakılmaz.
- Referanslı foreach sonrasında değişken unset edilir.
- Döngü içinde veritabanı sorgusu çalıştırmaktan kaçınılır; sorgu tek seferde yapılıp sonuç dizide gezilir.
- İç içe döngü yerine anahtar tabanlı arama tercih edilir.
PHP eğitim serisi
Bu yazı, temel sözdiziminden üretim ortamına kadar ilerleyen 25 bölümlük serinin bir parçası. Bölümler sırayla okunacak biçimde hazırlandı, ancak her biri tek başına da kullanılabilir.
Temeller
- Kurulum ve temel sözdizimi
- Döngüler ve akış kontrolü (bu yazı)
- Diziler
- Fonksiyonlar
- String fonksiyonları
- Süper globaller
- Form işleme
- Dosya işlemleri
Dilin ayrıntıları
Nesne yönelimli PHP
- Sınıf ve nesne
- Kalıtım, arayüz ve trait
- Statik üyeler, sabitler ve enum
- Namespace, Composer ve autoload
Veri ve güvenlik
- PDO ile veritabanı işlemleri
- Oturum yönetimi ve kimlik doğrulama
- Güvenli çıktı ve XSS
- JSON ile veri değişimi
Dış dünya ve üretim
Yorumlar
İlk yorumu sen yap.
İlgili Yazılar

PHP Uygulamasını Üretime Almak: Yapılandırma ve Güvenlik
Geliştirme makinesinde çalışan kod ile üretimde güvenle çalışan kod arasındaki fark yapılandırmadır. Ayarlar, izinler, dağıtım akışı ve son kontroller.

PHP ile REST API Yazmak: Yönlendirme ve HTTP Durum Kodları
Bir API'nin kalitesi çoğunlukla ayrıntılarda belli olur: doğru durum kodu, tutarlı hata biçimi ve öngörülebilir adresler. Saf PHP ile uçtan uca kurulum.

PHPUnit ile Birim Test Yazmak: Kurulum, Sahte Nesneler ve Kapsam
Testin amacı hata bulmak değil, değişikliği güvenle yapabilmektir. Kurulum, ilk test, sahte nesneler ve test edilebilir kodun özellikleri.