PHP/Akış denetimi ve döngüler

< PHP

Programın, akış içerisinde bir veya birkaç koşul dahilinde belirtilen işleri yapması ya da başka bir gidişata yönlendirilmesi akış denetimi olarak tanımlanabilir. Döngüleri de bir veya birkaç koşul dahilinde, belirtilen işlerin belli oranda tekrarlanması olarak tanımlayabiliriz.

Şu biçimde yazılır:

<?php
if(koşul)
{
    yapılacak işler
}
?>

if bloğunun çalışması için koşul ifadesinin boolean true döndürmesi gerekir. Dönen değer true ise yapılacak işler kısmı devreye girer.

<?php
$a = 5;
$b = 4;
if($a > $b)
{
    echo "a büyüktür b";
}
?>

Örnekte değeri 5 olan $a ve değeri 4 olan $b değişkenleri tanımlandı. if bloğunun koşul kısmında $a büyüktür $b şartı koşuldu. Buradan dönen değer true olacağından if bloğunun içindeki echo deyimi çalışacak ve a büyüktür b ifadesi çıktılanacaktır.

Yukarıdaki örnekte olduğu gibi koşul kısmında operatörler kullanılır.

<?php
$a = 5;
$b = 4;
$c = 6;
if($a > $b && $c > $a)
{
    echo "a büyüktür b ve c büyüktür a";
}
?>

Burada $a′nın $b′den ve $c′nin de $a′dan büyük olması şartı koşuldu. Koşul true değer üreteceğinden echo deyimi devreye girer. Ek bilgi için bkz: Operatörler

Başka bir örnek;

<?php
$a = 5;
if($a)
{
    echo "burası çalışır";
}
?>

Bu örnekte koşul true değer üreteceğinden ekrana burası çalışır çıktılanır. Başka bir örnek:

<?php
$a = 0;
if($a)
{
    echo "burası çalışır mı?";
}
?>

Buradaki koşul false değer üreteceğinden if bloğu çalışmaz. Yani if bloğunun içindeki echo deyimi işleme konulmaz. Ek bilgi için bkz: Boolean türe dönüşüm

<?php
$a = 16;
if($a % 2 == 0)
{
    echo "a çifttir<br>";
    $a *= 2;
    echo $a;
}
?>

Bu örnekte $a değişkeninin 2'ye bölümünden kalan 0 (sıfır) ise -yani $a çiftse- şartı koşuluyor. Koşul, true değer üreteceğinden if bloğu çalışır, a çifttir çıktılanır, $a'nın karesi alınır ve son olarak $a değişkeninin değeri (32) çıktılanır.

İç içe if blokları tanımlanabilir.

<?php
$a = 16;
if($a % 2 == 0)
{
    echo "a çifttir<br>";
    if($a > 10)
    {
        echo "ve a 10'dan büyüktür";
    }
}
?>

Örnekte, dıştaki if bloğu çalışır, içteki if bloğunun koşulu olan $a > 10 da true değer üreteceğinden içteki if bloğu da çalışır.

if bloğu dışında ikinci bir koşul tanımlanmasını ve farklı işler yapılmasını sağlar. Şöyle kullanılır:

<?php
if(koşul)
{
    yapılacak işler
}
elseif(başka koşul)
{
    başka yapılacak işler
}
?>

if bloğundaki koşul true değer üretirse if bloğu çalışır, elseif bloğu kontrol edilmez. Ancak if bloğu false değer üretirse elseif bloğunun koşuluna bakılır. Bu koşul true ise elseif bloğu çalıştırılır, aksi durumda elseif bloğu da es geçilir. Bir örnek:

<?php
$dil = "php";
if($dil == "python")
{
    echo "Guido van Rossum";
}
elseif($dil == "php")
{
    echo "Rasmus Lerdorf";
}
?>

Burada if bloğunun koşulu false üreteceğinden elseif bloğunun koşulu kontrol edilir, bu koşul da true döndüreceğinden elseif bloğu çalışır. if bloğu true değer üretseydi elseif bloğu hiç kontrol edilmeyecekti. Yani:

<?php
$dil = "php";
if($dil == "php")
{
    echo "Rasmus Lerdorf";
}
elseif($dil == "python")
{
    echo "Guido van Rossum";
}
?>

Yukarıda if bloğu çalışır, elseif kontrol edilmez.

Birden fazla elseif bloğu tanımlanabilir.

<?php
$not = 62;
if($not <= 24)
{
    echo "Okumaz";
}
elseif($not <= 44)
{
    echo "Yetersiz";
}
elseif($not <= 54)
{
    echo "Zeki ama çalışmıyor";
}
elseif($not <= 69)
{
    echo "Gayretli";
}
elseif($not <= 84)
{
    echo "İyi";
}
elseif($not <= 100)
{
    echo "Çalışkan";
}
?>

$not değişkeni <= 69 koşuluyla uyuştuğundan ilgili elseif bloğu çalışır ve ekrana Gayretli çıktılanır.

elseif bloklarının içinde yeni if - elseif blokları oluşturulabilir.

<?php
$a = 8;
if($a % 2 == 1)
{
    echo "a tektir<br>";
}
elseif($a % 2 ==0)
{
    echo "a çifttir<br>";
    if($a < 5)
    {
        echo "ve a 5'ten küçüktür";
    }
    elseif($a > 10)
    {
        echo "ve a 10'dan büyüktür";
    }
}
?>

Bu örnekte elseif bloğu çalışacaktır ve bu bloğun içindeki echo deyimi (a çifttir) işleme konacaktır. Daha sonra bu bloğun içindeki if deyimi kontrol edilir ancak bu kısım false üreteceğinden işleme konmaz. elseif bloğuna geçilir ama bu blok da false üreteceğinden o da çalıştırılmaz.

if ve elseif bloklarındaki koşullar sağlanmadığında yapılacak işler else bloğu içine alınır. Şu biçimde kullanılır:

<?php
else
{
    yapılacak işler
}
?>

else bloğunun herhangi bir koşul ifadesi almadığına dikkat ediniz. Çünkü else bloğu bir koşula bağlı olarak değil, if ve elseif blokları çalışmadığında devreye girer. Örneğin:

<?php
$a = 4;
if($a % 2 == 1)
{
    echo "a tektir";
}
else
{
    echo "a çifttir";
}
?>

Burada if bloğu false üreteceğinden else bloğu çalıştırılır. Başka bir örnek:

<?php
$dil = "java";
if($dil == "python")
{
    echo "php";
}
elseif($dil == "python")
{
    echo "python";
}
else
{
    echo "dil php veya python değil";
}
?>

Burada ise if ve elseif blokları false sonuç üreteceğinden else bloğu çalıştırılır.

else bloğu içinde if - elseif - else blokları tanımlanabilir.

<?php
if()
{
}
else
{
    if()
    {
    }
    elseif()
    {
    }
    else
    {
    }
}
?>

if - elseif - else bloklarında PHP kipinden çıkıp HTML'e geçilebilir. Bunun için bloklar şu biçimde yazılır:

<?php if(koşul): ?>

    // HTML kipi

<?php elseif(koşul): ?>

    // HTML kipi

<?php else: ?>

    // HTML kipi

<?php endif; ?>

Bu tip kullanımlarda koşullardan sonra iki nokta üst üste ve tüm bloklardan sonra endif kullanıldığına dikkat ediniz.

Bir örnek:

<?php
$wikimedia = "Wikibooks";
?>

<?php if($wikimedia == "Wikipedia"): ?>

    <span id="ansiklopedi"><?php echo $wikimedia; ?></span>

<?php elseif($wikimedia == "Wiktionary"): ?>

    <span id="sozluk"><?php echo $wikimedia; ?></span>

<?php elseif($wikimedia == "Wikiquote"): ?>

    <span id="ozdeyis"><?php echo $wikimedia; ?></span>

<?php else: ?>

    <span id="kitap"><?php echo $wikimedia; ?></span>

<?php endif; ?>

Bu kullanım genellikle PHP kipinden çıkıp HTML kipine geçmek için kullanılır ancak PHP betiklerinin içinde de kullanılabilir. Örneğin:

<?php
$wikimedia = "Wikibooks";
if($wikimedia == "Wikipedia"):
    echo "ansiklopedi";
elseif($wikimedia == "Wikiquote"):
    echo "özdeyiş";
else:
    echo "kitap";
endif;
?>

switch denetimi, bir değişken veya ifadenin alabileceği değerlere göre farklı işler yapılmasını sağlar. Kullanılış biçimi:

<?php
switch(ifade)
{
    case değer:
        yapılacak işler
        break;
    case başka değer:
        yapılacak işler
        break;
    default:
        yapılacak işler
}
?>

ifade, case deyiminden sonra gelen hangi değerle eşleşiyorsa o bloktaki işlemler yapılır. ifade hiçbir case ile eşleşmiyorsa default bloğu çalıştırılır. Bir örnek:

<?php
$wikimedia = "Wikibooks";
switch($wikimedia)
{
    case "Wikipedia":
        echo "Özgür Ansiklopedi";
        break;
    case "Wikibooks":
        echo "Özgür Kütüphane";
        break;
    default:
        echo "Diğer Projeler";
}
?>

Burada $wikimedia isimli ve Wikibooks değerli bir değişken ve bu değişkenin değerini temel alan bir switch denetimi tanımlandı. $wikimedia değişkeni, case "Wikibooks" değeri ile eşleşeceğinden bu case bloğu çalıştırılacaktır.

break komutu, eşleşen case bloğundaki işlemler yapıldıktan sonra, switch denetiminden çıkılmasını sağlar. break kullanılmayan bir örnek:

<?php
$wikimedia = "Wikipedia";
switch($wikimedia)
{
    case "Wikipedia":
        echo "Özgür Ansiklopedi";
    case "Wikibooks":
        echo "Özgür Kütüphane";
        break;
    default:
        echo "Diğer Projeler";
}
// Çıktısı: Özgür AnsiklopediÖzgür Kütüphane
?>

Burada $wikimedia değişkeni ilk case bloğuyla eşleşir. Bu bloktaki işlemler yapılır, ancak break komutu verilmediği için bir sonraki case bloğu da çalıştırılır. İlk bakışta bu bir yanlışlık olarak düşünülse de, aslında istenen şey de olabilir. Başka bir örnek:

<?php
switch($meyve)
{
    case "portakal":
    case "mandalina":
    case "elma":
    case "çilek":
        echo "Severim";
        break;
    case "erik":
        echo "Sevmem";
        break;
    case "kızılcık":
        echo "Hiç tatmadım";
}
?>

Burada $meyve değişkeni portakal, mandalina, elma veya çilek değeri alırsa case çilek: bloğu çalışacaktır. Bunun gibi break komutu kullanmadan gruplamalar yapılabilir.

default bloğu ile ilgili bir örnek:

<?php
$a = 8;
switch($a)
{
    case 4:
        echo "a dörttür";
        break;
    case 5:
        echo "a beştir";
        break;
    default:
        echo "a herhangi bir sayıdır";
}
?>

Burada $a değişkeni herhangi bir case bloğuyla eşleşmeyeceğinden default bloğu çalıştırılır.

switch denetimlerinde, son blokta break komutu kullanılmasına gerek yoktur. Çünkü adı üstünde son bloktur, ondan sonra gelecek herhangi bir case bloğu olmayacaktır.

switch denetimleri şu biçimde de yazılabilir:

<?php
switch(ifade):
    case değer:
        yapılacak işler
        break;
    case başka değer:
        başka yapılacak işler
        break
    default:
        yapılacak işler
endswitch;
?>

Bu söz dizimi, PHP kipinden çıkıp HTML'e geçmek için de kullanılabilir. Örneğin:

<?php switch(ifade):
case değer: ?>

     // HTML kipi

<?php break; ?>
<?php case başka değer: ?>

    // HTML kipi

<?php break; ?>
<?php default: ?>

    // HTML kipi

<?php endswitch; ?>

Koşul sağlandığı müddetçe birtakım işlerin yapılmasını sağlar. Kullanılış biçimi:

<?php
while(koşul)
{
    yapılacak işler
}
?>

while döngüsü şu mantıkla çalışır:

  • koşul ifadesi kontrol edilir
  • koşul sağlanıyorsa while bloğu içindeki işlemler yapılır
  • Başa dönülür ve koşul kontrol edilir.
  • koşul hala sağlanıyorsa blok içindeki kodlar çalıştırılır, koşul sağlanmıyorsa döngüden çıkılır

Döngüden çıkabilmek için belli bir noktadan sonra koşulun false değer üretmesi gerekir. Aksi durumda sonsuz döngü oluşur.

<?php
$a = 4;
while($a == 4)
{
    echo $a;
}
// BUNU EVDE DENEMEYİN!
?>

Bu örnekte koşul daima sağlanacağından while bloğu içindeki echo komutu daima çalışacak ve bir sonsuz döngü oluşacaktır. Döngünün bir noktadan sonra kırılması gerekir. Örneğin:

<?php
$a = 1;
while($a < 10)
{
    echo "{$a}<br>";
    $a++;
}
?>

Burada değeri 1 olan $a değişkeni tanımlandı ve while döngüsüne koşul olarak $a, 10'dan küçük olduğu müddetçe çalış emri verildi. while bloğu içinde de bir echo komutu verildi ve daha sonra $a nın değeri bir artırıldı. Döngünün her iterasyonunda $a bir artacağından bir müddet sonra -yani $a 10 olduğunda- koşul sağlanamayacak ve döngüden çıkılacaktır. Yukarıdaki örneğin çıktısı:

1
2
3
4
5
6
7
8
9

Döngünün son iterasyonunda $a 10 değerini aldığı için ve 10 < 10 koşulu sağlanamadığı için döngüden çıkılmıştır.

while döngüsü şu biçimde de kullanılabilir:

<?php
while(koşul):
    birtakım işler
    başka işler
endwhile;
?>

Veya şöyle:

<?php while(koşul): ?>

    // HTML kipi

<?php endwhile; ?>

do-while

değiştir

Kullanılış biçimi:

<?php
do
{
    yapılacak işler
}
while(koşul)
?>

Şu mantıkla çalışır:

  • İlk seferde, herhangi bir koşula bakılmaksızın do bloğundaki işlemler yapılır
  • while deyiminin parantezlerindeki koşul kontrol edilir
  • koşul sağlanıyorsa do bloğu tekrar çalıştırılır, koşul sağlanmıyorsa döngüden çıkılır.

while döngüsünde olduğu gibi sonsuz döngü oluşmaması için döngünün bir noktadan sonra kırılması gerekir.

Kullanımıyla ilgili bir örnek:

<?php
$a = 1;
do
{
    $kare = $a * $a;
    echo "Karesi: {$kare}<br>";
    $a++;
}
while($a < 10)
?>

Burada do bloğu ilk seferde sorgusuz sualsiz çalıştırılır. Daha sonra while deyiminin parantezlerindeki koşul'a bakılır. Koşul sağlanmayana kadar do bloğu çalıştırılır. Yukarıdaki örneğin çıktısı:

Karesi: 1
Karesi: 4
Karesi: 9
Karesi: 16
Karesi: 25
Karesi: 36
Karesi: 49
Karesi: 64
Karesi: 81

while döngüsüne benzer. Bir koşul dahilinde birtakım işlerin belli sayıda tekrarlanarak yapılmasını sağlar. Söz dizimi:

<?php
for(ifade1;ifade2;ifade3)
{
    yapılacak işler
}
?>
  • ifade1, döngü çalışmaya başladığında çalıştırılır. Daha sonra işleme konmaz.
  • ifade2, koşul ifadesidir. Döngünün hangi şarta bağlı olarak tekrarlanacağını belirtir.
  • ifade3, döngünün her iterasyonundan sonra çalıştılır.

Bir örnek:

<?php
for($a = 1;$a < 10;$a++)
{
    echo "{$a}<br>";
}
?>

Bu örnekte, döngüye girildiği anda $a = 1 ataması işleme konur. $a < 10 koşuluna bakılır, koşul sağlanıyorsa döngünün ilk iterasyonu gerçekleşir. $a++ ifadesi çalıştırılır, koşul true değer üretiyorsa ikinci iterasyona geçilir; false değer üretiyorsa döngüden çıkılır. Yurakıdaki örneğin çıktısı:

1
2
3
4
5
6
7
8
9

1'den 15'a kadar tek sayıları çıktılayan basit bir örnek:

<?php
for($a = 1;$a < 15;$a += 2)
{
    echo "{$a}<br>";
}
?>

Bu döngü ilk çalıştığında $a değişkenine 1 değeri atanır. $a < 15 koşulu sağlandığından döngünün ilk iterasyonu başlar ve echo ile $a′nın değeri çıktılanır ve ilk iterasyon sonlanır. $a += 2 ifadesi işleme konur. Koşula bakılır. Örneğin çıktısı:

1
3
5
7
9
11
13

İç içe for döngüleri tanımlanabilir.

<?php
for($a = 1;$a < 4;$a++)
{
	echo "dış döngüdeyiz. a = {$a}<br>";
	for($b = 1;$b < 4;$b++)
	{
		echo "iç döngüdeyiz. b = {$b}<br>";
	}
}
?>

Çıktısı:

dış döngüdeyiz. a = 1
iç döngüdeyiz. b = 1
iç döngüdeyiz. b = 2
iç döngüdeyiz. b = 3
dış döngüdeyiz. a = 2
iç döngüdeyiz. b = 1
iç döngüdeyiz. b = 2
iç döngüdeyiz. b = 3
dış döngüdeyiz. a = 3
iç döngüdeyiz. b = 1
iç döngüdeyiz. b = 2
iç döngüdeyiz. b = 3

for döngüleri şu söz dizimi ile de kullanılabilir:

<?php
for(ifade1;ifade2;ifade3):
    yapılacak işler
    başka işler
endfor;
?>

PHP kipinden çıkıp HTML'e de geçilebilir.

<?php for(ifade1;ifade2;ifade3): ?>

    // HTML kipi

<?php endfor; ?>

continue

değiştir

continue deyimi, döngünün o anki iterasyonunun sonlanıp bir sonrakine geçilmesini sağlar.

<?php
for($a = 1;$a <= 5;$a++)
{
	if($a == 3)
	{
		continue;
	}
	echo "{$a}<br>";
}
?>

Çıktısı:

1
2
4
5

Görüldüğü gibi $a 3 değerini aldığında, continue deyiminin etkisiyle ekrana çıktılanmadan bir sonraki iterasyona geçildi.

continue deyimiyle, mevcut döngüde başa dönülebileceği gibi üst döngülerden birine de geçilebilir. Örneğin:

<?php
$a = 4;
while($a > 1) // dış döngü
{
	echo "dış döngüdeyiz<br>";
	$a--;
	while(1) // iç döngü
	{
		echo "iç döngüdeyiz<br>";
		continue 2;
	}
	echo "burası çalışır mı?";
}
echo "döngülerin dışındayız";
?>

Burada iç içe iki while döngüsü var. Dıştaki döngü çalıştığında dış döngüdeyiz çıktılanır ve $a bir eksiltilir. İçteki döngü çalışmaya başlar ve iç döngüdeyiz çıktılanır. continue 2 deyiminin etkisiyle bir üstteki döngüye (yani dış döngü) geçilir ve bundan sonraki kısım işleme konmaz. Yani echo "burası çalışır mı?" ifadesi hiçbir zaman işleme konmayacaktır. Bir önceki örnekte continue deyimi, for döngüsünde başa dönmemizi sağlamıştı. Buradaki continue 2 ifadesi ise mevcut döngünün bir üstündeki döngünün başına dönmemizi sağladı. Ayrıca içteki while döngüsünün koşulu olan (1) ifadesi kafanızı karıştırdıysa bkz: Boolean türe dönüşüm

Yukarıdaki örneğin çıktısı:

dış döngüdeyiz
iç döngüdeyiz
dış döngüdeyiz
iç döngüdeyiz
dış döngüdeyiz
iç döngüdeyiz
döngülerin dışındayız

break deyimine switch denetiminde değinilmişti. switch bloğundan çıkmayı sağlıyordu. Bu deyim döngülerle de kullanılabilir. Örneğin:

<?php
for($a = 7;$a > 0;$a--)
{
    if($a == 4)
    {
        break;
    }
    echo "{$a}<br>";
}
?>

Çıktısı:

7
6
5

Görüldüğü gibi $a 4 değerini aldığında break komutu sayesinde döngü sonlandı ve diğer iterasyonlar işleme konmadı.

break komutu ile mevcut döngüden çıkılabileceği gibi üst döngüden de çıkılabilir. Söz dizimi olarak ifade etmek gerekirse:

<?php
while()
{
    switch()
    {
        case :
            break; // switch denetiminden çıkar
        case :
            break 2; // hem switch denetiminden hem de while döngüsünden çıkar
    }
}
?>

Diziler (array) üzerinde döngü kurmaya yarar. İlgili olarak bkz: Diziler

<?php
$dizi = array("a", "b", "c", "d");
foreach($dizi as $deger)
{
    echo "{$deger}<br>";
}
?>

Burada foreach, $dizi üzerinde bir döngü kuruyor ve döngünün her iterasyonunda $dizinin bir değerini $deger değişkenine atıyor. Çıktısı:

a
b
c
d

Başka bir örnek:

<?php
$dizi = array("a", "b", "c", "d");
foreach($dizi as $anahtar => $deger)
{
    echo "{$anahtar} => {$deger}<br>";
}
?>

Bu örnekte de her iterasyonda $deger değişkenine sırası gelen değer atanırken aynı zamanda $anahtar değişkenine o değerin anahtarı atanıyor. Çıktısı:

0 => a
1 => b
2 => c
3 => d

Şimdi de 4 adet tamsayı değer tutan dizinin, değerlerini kareleriyle değiştirelim ve dizinin bilgilerini var_dump() ile çıktılayalım.

<?php
$dizi = array(2, 3, 4, 5);
foreach($dizi as $deger)
{
    $deger *= 2;
}
var_dump($dizi);
?>

Çıktısı:

array(4) {
  [0]=>
  int(2)
  [1]=>
  int(3)
  [2]=>
  int(4)
  [3]=>
  int(5)
}

$deger değişkeninin değerini 2 ile çarpıp tekrar kendisine atamamıza rağmen dizide bir değişme olmadı. Çünkü gönderimli atama yapmadık. Bir de gönderimli atama yaparak deneyelim:

<?php
$dizi = array(2, 3, 4, 5);
foreach($dizi as &$deger) // $deger artık gönderimli
{
    $deger *= 2;
}
var_dump($dizi);
?>

Yeni çıktı:

array(4) {
  [0]=>
  int(4)
  [1]=>
  int(6)
  [2]=>
  int(8)
  [3]=>
  &int(10)
}

Görüldüğü gibi $deger değişkenindeki bir değişiklik dizideki orijinal değerleri de etkiledi.

foreach döngülerinde gönderimli atama yapıldığında, $deger değişkeni, dizinin son elemanına gönderimli olarak kalır. Yani:

<?php
$dizi = array(2, 3, 4, 5);
foreach($dizi as &$deger) // $deger artık gönderimli
{
    $deger *= 2;
}
echo $deger; // 10 çıktılar
unset($deger); // gönderim kaldırıldı. $deger artık NULL (tanımsız)
?>

İlgili olarak bkz: Değişkenlerde gönderimli atama

foreach ile döngü kurulacak olan dizi çok boyutluysa iç içe foreach tanımları yapılabilir. Örneğin:

<?php
$dizi = array("meyve" => array("portakal", "elma"),
              "sebze" => array("pırasa", "ıspanak"));
foreach($dizi as $deger1)
{
    foreach($deger1 as $deger2)
    {
        echo "{$deger2}<br>";
    }
}
?>

Çıktısı:

portakal
elma
pırasa
ıspanak