---
title: 'Çok Boyutlu Diziler'
source: 'https://academia.sh/tr/kurslar/php-temelleri/cok-boyutlu-diziler'
course: 'PHP Temelleri'
language: tr
updated: '2026-10-21T05:03:33+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Dizi elemanı olarak dizi kullanarak iç içe veri modelini kurar ve her düzeyde anahtarla erişir'
    - 'Eksik iç anahtarın E_WARNING ve null ürettiğini ölçer ve uyarı sınıfına yazar'
    - 'Boşluk birleştirme işlecinin yolun tamamını sessize çevirdiğini ve okuma ile yazmanın ayrı kanal olduğunu gösterir'
---

# Çok Boyutlu Diziler

Dizilerin dizilerle iç içe kurulması; eksik bir iç anahtarın E_WARNING ile null vermesi; null üzerinde dizi erişimi; boşluk birleştirme işlecinin yolun tamamını sessize çevirmesi; okuma ile yazmanın ayrı kanal olması.

İndeksli ve İlişkisel Diziler dersi, aynı anahtarın farklı yazımlarının tek elemana inmesini ve bunun hiçbir kanaldan duyulmadığını ölçtü. Anahtar tek bir değerdi. Bir elemanın kendisi başka bir dizi olduğunda erişim bir yola dönüşür: `$a[0]['soyad']` iki ayrı arama yapar ve ikincisinin dayanağı birincinin sonucudur. Bu ders yolun bir halkası eksik olduğunda bunun nereden duyulduğunu ölçüyor.

Çok boyutlu dizi (multidimensional array) ayrı bir tip değildir; elemanları dizi olan sıradan bir dizidir. Derinlik için dilde bir sınır konmaz, yalnız bellek sınırlar. Ders sınıf adlarını önceki derslerdeki anlamıyla kullanır: **sessiz**, **dönüş**, **uyarı**, **durdurur**.

## İç İçe Veri Modelleme

Bir öğrenci listesi, her öğrencinin adı ve not tablosuyla birlikte iç içe bir yapıya oturur. Aşağıdaki dosya bu yapıyı kuruyor, iki düzeyden okuyor ve `count` ile düz sayımı özyinelemeli sayımla karşılaştırıyor.

```php
<?php
// ogrenciler.php — dizi icinde dizi ile veri modelleme
$ogrenciler = [
    ['ad' => 'Ada', 'notlar' => ['mat' => 80, 'fen' => 90]],
    ['ad' => 'Can', 'notlar' => ['mat' => 70, 'fen' => 60]],
];

foreach ($ogrenciler as $sira => $ogrenci) {
    $ortalama = array_sum($ogrenci['notlar']) / count($ogrenci['notlar']);
    echo $sira, ' ', $ogrenci['ad'], ' ', $ortalama, "\n";
}

echo 'Can fen: ', $ogrenciler[1]['notlar']['fen'], "\n";
echo 'duz sayim: ', count($ogrenciler), "\n";
echo 'ozyinelemeli sayim: ', count($ogrenciler, COUNT_RECURSIVE), "\n";
```

```
0 Ada 85
1 Can 65
Can fen: 60
duz sayim: 2
ozyinelemeli sayim: 10
```

Her düzey kendi anahtar uzayına sahiptir. Dış dizi indeksli, öğrenci kaydı ilişkisel, not tablosu yine ilişkisel; `$ogrenciler[1]['notlar']['fen']` üç anahtarın sırayla uygulanmasıdır. `count` yalnız dış düzeyi sayar, `COUNT_RECURSIVE` bayrağı her iç diziyi hem bir eleman olarak hem içeriğiyle sayar; bu yüzden iki sayı arasındaki fark yapının derinliğini yansıtır, veri sayısını değil.

**DZ6.** Bu derste kayıtlar sabit biçimlidir: her öğrencide `ad` ve `notlar` anahtarı vardır. Yolun bozulduğu durumlar bir sonraki bölümde ayrıca kurulur. Bir kaydın biçiminin kullanıcıdan ya da dış bir kaynaktan geldiği durumlar M16/K01'in konusudur ve burada ele alınmaz.

## Eksik İç Anahtar

Yol bir halkada kopunca ne olduğu, dinleyicinin kanal sırasıyla ölçülür. Dersin ortak yardımcısı `kanal.php` aşağıda tam metniyle veriliyor; çıktı bloğu olmadığı için yalnız diske yazılır.

```php
<?php
// kanal.php — bir sorunun hangi kanaldan duyuldugunu siniflandiran yardimcilar

// Yakalanan uyarilarin seviye adlari burada birikir; ileti metni tutulmaz.
$GLOBALS['duyulan_uyarilar'] = [];

set_error_handler(function (int $seviye): bool {
    $adlar = [E_WARNING => 'E_WARNING', E_NOTICE => 'E_NOTICE', E_DEPRECATED => 'E_DEPRECATED'];
    $GLOBALS['duyulan_uyarilar'][] = $adlar[$seviye] ?? 'E_' . $seviye;
    return true;
});

// Degeri tipiyle birlikte kisa bir metne cevirir.
function yaz(mixed $deger): string
{
    return match (true) {
        $deger === null => 'null',
        is_bool($deger) => $deger ? 'true' : 'false',
        is_array($deger) => 'dizi(' . count($deger) . ')',
        default => get_debug_type($deger) . ' ' . $deger,
    };
}

// Isi calistirir ve sorunun hangi kanaldan duyuldugunu sirayla sorar:
// once firlatma, sonra uyari, sonra false/null donus; hicbiri yoksa sessiz.
function dinle(callable $is): array
{
    $GLOBALS['duyulan_uyarilar'] = [];
    try {
        $sonuc = $is();
    } catch (Throwable $hata) {
        return ['durdurur', get_class($hata)];
    }
    if ($GLOBALS['duyulan_uyarilar']) {
        $seviyeler = implode(',', array_unique($GLOBALS['duyulan_uyarilar']));
        return ['uyari', $seviyeler . ', sonuc ' . yaz($sonuc)];
    }
    if ($sonuc === false || $sonuc === null) {
        return ['donus', 'sonuc ' . yaz($sonuc)];
    }
    return ['sessiz', 'sonuc ' . yaz($sonuc)];
}

// Kodu ayri bir PHP yurutmesinde calistirir; cikis kodu 255 ise yurutme durmustur.
function ayri_yurut(string $kod): array
{
    exec('php -d display_errors=0 -r ' . escapeshellarg($kod) . ' 2>&1', $satirlar, $cikis);
    $sinif = $cikis === 255 ? 'durdurur' : 'sessiz';
    return [$sinif, 'cikti ' . count($satirlar) . ' satir, cikis ' . $cikis];
}
```

```php
<?php
// eksik.php — eksik ic anahtar ve null uzerinde dizi erisimi
require 'kanal.php';

$kayitlar = [['ad' => 'Ada']];

$gozlemler = [
    'eksik ic anahtar'   => fn() => $kayitlar[0]['soyad'],
    'eksik dis anahtar'  => fn() => $kayitlar[5]['ad'],
    'null uzerinde erisim' => fn() => $kayitlar[5]['ad']['x'],
    'dizgi uzerinde erisim' => fn() => $kayitlar[0]['ad']['x'],
];

foreach ($gozlemler as $ad => $gozlem) {
    [$sinif, $kanit] = dinle($gozlem);
    printf("%-23s%-9s%s\n", $ad, $sinif, $kanit);
}
```

```
eksik ic anahtar       uyari    E_WARNING, sonuc null
eksik dis anahtar      uyari    E_WARNING, sonuc null
null uzerinde erisim   uyari    E_WARNING, sonuc null
dizgi uzerinde erisim  durdurur TypeError
```

Birinci satır kursun `eksik ic anahtar` gözlemidir: `$kayitlar[0]['soyad']` değeri `null` verdi ve `E_WARNING` bildirdi. Sınıf **uyarı**. Yürütme sürdü; sonuç `null` olduğu için çağıran kod hata olduğunu ancak değerle birlikte gelen uyarıdan anlar. Önceki dersin sessizliğiyle bu ders arasındaki ayrım budur: anahtar yazımındaki kayıp duyulmuyordu, anahtar okumadaki kayıp duyuluyor.

İkinci satır dış düzeyden eksik bir indeks için aynı sonucu veriyor, üçüncü satır ise zincirin ilk halkası zaten `null` iken ikinci erişimin de aynı seviyeyi bildirdiğini gösteriyor: `null` üzerinde dizi erişimi hata değil uyarıdır ve `null` yine `null` döner. Zincir ne kadar uzarsa uzasın bir kopukluk sonrasındaki her erişim sessizce `null`'a çıkar; kopukluğun hangi halkada olduğu uyarı metninden okunur, sonuçtan okunmaz. Dördüncü satır sınırı gösteriyor: yol bir dizgiye vardığında ve dizgiye `'x'` gibi bir dizgi anahtarı uygulandığında `null` dönmez, `TypeError` fırlar; sınıf **durdurur**. Uyarı kanalı yalnız `null` ya da eksik anahtar için işler, tipi yanlış bir değere uygulanan erişim için işlemez.

**DZ7.** Uyarının ileti metni ve satır bilgisi ortama bağlıdır ve ders onları basmaz; yalnız seviye adı (`E_WARNING`) ve sonucun tipi basılır. Aynı kopukluğun bir ayarla durduran bir hataya çevrilmesi mümkündür, ancak ders hiçbir ini değerine güvenmez ve bu yolu ölçmez.

## Boşluk Birleştirme ile Sessizlik

Boşluk birleştirme işleci (null coalescing, `??`) sol tarafın değerini, o `null` ya da tanımsız ise sağ tarafı verir. Eksik yol üzerinde uygulandığında zincirin her halkasındaki uyarıyı bastırır.

```php
<?php
// birlestirme.php — ?? eksik yolu sessize cevirir
require 'kanal.php';

$veri = ['a' => 1];
$kayitlar = [['ad' => 'Ada']];

$gozlemler = [
    'uyarili okuma'     => fn() => $veri['b'],
    'birlestirmeli'     => fn() => $veri['b'] ?? 0,
    'derin birlestirme' => fn() => $kayitlar[3]['notlar']['fen'] ?? -1,
    'var olan deger'    => fn() => $kayitlar[0]['ad'] ?? 'yok',
];

foreach ($gozlemler as $ad => $gozlem) {
    [$sinif, $kanit] = dinle($gozlem);
    printf("%-19s%-9s%s\n", $ad, $sinif, $kanit);
}
```

```
uyarili okuma      uyari    E_WARNING, sonuc null
birlestirmeli      sessiz   sonuc int 0
derin birlestirme  sessiz   sonuc int -1
var olan deger     sessiz   sonuc string Ada
```

Aynı eksik anahtar iki kanalda duyuldu: yalın okuma **uyarı**, `??` ile **sessiz**. Üçüncü satır daha önemli: `??` yalnız son halkayı değil, yolun tamamını sarar; üç düzeyli bir yolda herhangi bir halka eksikse sonuç varsayılan değerdir ve hiçbir kanaldan haber gelmez. Bu işlecin amacıdır, ancak amaç sorunun kaybolması anlamına da gelir: yol yanlış yazılmışsa (`'not'` yerine `'notlar'`), `??` yazımı hatayı da aynı sessizlikle örter.

## Kayıt Listesi ile Çalışmak

İç içe diziler pratikte çoğu zaman bir kayıt listesi biçimindedir: dış dizi indeksli, her eleman aynı anahtarları taşıyan ilişkisel bir dizi. Bu biçim için üç sık iş vardır: bir sütunu çekmek, kayıtları bir anahtara göre sıralamak, kayıtları o sütuna göre indekslemek.

```php
<?php
// kayitlar.php — kayit listesinde sutun, siralama ve indeksleme
$kayitlar = [
    ['id' => 7, 'ad' => 'Can', 'yas' => 31],
    ['id' => 3, 'ad' => 'Ada', 'yas' => 36],
    ['id' => 9, 'ad' => 'Efe', 'yas' => 24],
];

echo 'adlar: ', implode(',', array_column($kayitlar, 'ad')), "\n";
echo 'id ile indeksli: ', implode(',', array_keys(array_column($kayitlar, 'ad', 'id'))), "\n";

usort($kayitlar, fn($sol, $sag) => $sol['yas'] <=> $sag['yas']);
echo 'yasa gore: ', implode(',', array_column($kayitlar, 'ad')), "\n";

$kayitlar[1]['yas'] += 1;
echo 'guncel yas: ', $kayitlar[1]['yas'], "\n";
echo 'ortalama yas: ', array_sum(array_column($kayitlar, 'yas')) / count($kayitlar), "\n";
```

```
adlar: Can,Ada,Efe
id ile indeksli: 7,3,9
yasa gore: Efe,Can,Ada
guncel yas: 32
ortalama yas: 30.666666666667
```

`array_column` bir sütunu düz bir diziye çevirir; üçüncü argüman verilirse sonucun anahtarları o sütundan gelir. `usort` kayıtları verilen karşılaştırmaya göre yeniden diziler ve anahtarları yeniden numaralar. Ardından `$kayitlar[1]['yas'] += 1` yazımı iki düzeyli bir yola yazıyor; yol var olduğu için hiçbir şey bildirilmiyor. Kayıt listesi ile çalışan kodun çoğu bu üç fonksiyonla ve iki düzeyli indekslemeyle yazılır; hata, kayıtlar aynı biçimde olmadığında ortaya çıkar.

**DZ8.** Kayıtların biçimi bu derste kod içinde sabittir. Aynı listeyi bir dosyadan ya da bir istekten okuyan kodun kayıt biçimini doğrulaması gerekir; bu doğrulama burada yapılmaz; kayıt biçimini sınayan fonksiyon bu dersin kapsamı dışındadır.

Bir kaydın bir anahtarı eksik olduğunda, sütunu çekmek ile her kayıttan anahtarı tek tek okumak ayrı kanallardan duyulur.

```php
<?php
// eksiksutun.php — array_column eksik anahtari sessizce atlar
require 'kanal.php';

$kayitlar = [
    ['ad' => 'Ada', 'soyad' => 'Yilmaz'],
    ['ad' => 'Can'],
    ['ad' => 'Efe', 'soyad' => 'Kaya'],
];

$gozlemler = [
    'array_column' => fn() => array_column($kayitlar, 'soyad'),
    'tek tek okuma' => fn() => array_map(fn($k) => $k['soyad'], $kayitlar),
    'birlesimli okuma' => fn() => array_map(fn($k) => $k['soyad'] ?? '-', $kayitlar),
];

foreach ($gozlemler as $ad => $gozlem) {
    [$sinif, $kanit] = dinle($gozlem);
    printf("%-17s%-9s%s\n", $ad, $sinif, $kanit);
}

echo 'sutun uzunlugu: ', count(array_column($kayitlar, 'soyad')), "\n";
echo 'kayit sayisi: ', count($kayitlar), "\n";
```

```
array_column     sessiz   sonuc dizi(2)
tek tek okuma    uyari    E_WARNING, sonuc dizi(3)
birlesimli okuma sessiz   sonuc dizi(3)
sutun uzunlugu: 2
kayit sayisi: 3
```

`array_column` eksik anahtarı olan kaydı sessizce atladı: sütun üç yerine iki eleman taşıyor ve **sessiz** sınıfındadır. Tek tek okuma aynı kayıtta `E_WARNING` verdi ve **uyarı** sınıfındadır; `??` ile okuma ise yedek değeri verip sessizleşti. Üç yazım aynı eksikliğe üç farklı tepki gösterdi. Dikkat edilecek yer şudur: `array_column` sonucu ile kayıt listesi artık aynı uzunlukta değildir, bu yüzden ikisini indeksle eşleştiren bir kod sessizce yanlış kaydı eşleştirir.

## Dizi Açma ve Özyinelemeli Birleştirme

İç içe bir dizinin parçalarını değişkenlere dağıtan dizi açma (destructuring) yazımı, yolun eksik olduğu durumda da kendi kanalını kullanır. İç içe iki dizinin birleştirilmesi ise düz birleştirmeden ayrı fonksiyonlarla yapılır.

```php
<?php
// acma.php — dizi acma ve ozyinelemeli birlestirme
require 'kanal.php';

$gozlemler = [
    'tam acma'       => fn() => (function () { [$x, $y] = [1, 2]; return $x + $y; })(),
    'eksik indeks'   => fn() => (function () { [$x, $y] = [1]; return $y; })(),
    'eksik anahtar'  => fn() => (function () { ['ad' => $ad, 'yas' => $yas] = ['ad' => 'Ada']; return $yas; })(),
    'ic ice acma'    => fn() => (function () { [[$p, $q], [$r]] = [[1, 2], [3]]; return $p + $q + $r; })(),
    'eksik ic acma'  => fn() => (function () { [[$p], [$r]] = [[1]]; return $r; })(),
];

foreach ($gozlemler as $ad => $gozlem) {
    [$sinif, $kanit] = dinle($gozlem);
    printf("%-15s%-9s%s\n", $ad, $sinif, $kanit);
}

$sol = ['a' => ['x' => 1, 'y' => 2], 'b' => 3];
$sag = ['a' => ['y' => 20, 'z' => 30], 'b' => 4];
echo 'array_merge: ', json_encode(array_merge($sol, $sag)), "\n";
echo 'array_replace: ', json_encode(array_replace($sol, $sag)), "\n";
echo 'array_replace_recursive: ', json_encode(array_replace_recursive($sol, $sag)), "\n";
echo 'array_merge_recursive: ', json_encode(array_merge_recursive($sol, $sag)), "\n";
```

```
tam acma       sessiz   sonuc int 3
eksik indeks   uyari    E_WARNING, sonuc null
eksik anahtar  uyari    E_WARNING, sonuc null
ic ice acma    sessiz   sonuc int 6
eksik ic acma  uyari    E_WARNING, sonuc null
array_merge: {"a":{"y":20,"z":30},"b":4}
array_replace: {"a":{"y":20,"z":30},"b":4}
array_replace_recursive: {"a":{"x":1,"y":20,"z":30},"b":4}
array_merge_recursive: {"a":{"x":1,"y":[2,20],"z":30},"b":[3,4]}
```

Dizi açma, eksik indekste ya da eksik anahtarda `E_WARNING` verir ve değişken `null` kalır; yani doğrudan indeksle okumanın uyarı sınıfı açmada da geçerlidir. Tam eşleşen açma ve iç içe açma sessizdir.

Özyinelemeli birleştirmede dört fonksiyon üç ayrı sonuç verir. `array_merge` ve `array_replace` iç dizileri bütün olarak değiştirir, `x` anahtarı kaybolur. `array_replace_recursive` iç dizilere iner ve `x`'i korur. `array_merge_recursive` ise çakışan skaler değerleri dizi hâline getirir: `y` için `[2,20]`, `b` için `[3,4]`. Toplam değerin tipinin sessizce değişmesi, sonradan `b`'yi sayı varsayan kodu bozabilecek bir ayrıntıdır.

## Sınırlayıcı Ölçüm

Eksik yola okumak uyarı veriyordu. Aynı eksik yola yazmak ise ayrı bir kanaldır.

```php
<?php
// yazma.php — eksik yola yazma ve okuma ayri kanal
require 'kanal.php';

$gozlemler = [
    'bos diziye derin yazma' => function () {
        $a = [];
        $a['x']['y'] = 1;
        return $a;
    },
    'ayni yoldan okuma' => function () {
        $a = [];
        return $a['x']['y'];
    },
    'varolan skalere yazma' => function () {
        $a = ['x' => 5];
        $a['x']['y'] = 1;
        return $a;
    },
];

foreach ($gozlemler as $ad => $gozlem) {
    [$sinif, $kanit] = dinle($gozlem);
    printf("%-24s%-9s%s\n", $ad, $sinif, $kanit);
}

$a = [];
$a['x']['y'] = 1;
echo 'kurulan yapi: ', json_encode($a), "\n";
```

```
bos diziye derin yazma  sessiz   sonuc dizi(1)
ayni yoldan okuma       uyari    E_WARNING, sonuc null
varolan skalere yazma   durdurur Error
kurulan yapi: {"x":{"y":1}}
```

Boş bir diziye `$a['x']['y'] = 1` yazmak iç diziyi kendiliğinden kurar ve hiçbir seviye bildirmez: sınıf **sessiz**. Aynı yoldan okumak ise uyarı verir. Okuma ve yazma ayrı kanallardır; birinde duyulan sorun diğerinde duyulmaz. Üçüncü satır ayrımın sınırını çiziyor: yol üzerindeki mevcut değer bir skaler ise, yazma artık kendiliğinden kurmaz ve durdurur.

**DZ9.** Yazmanın sessizliği bir kolaylık olarak tasarlanmıştır ve yanlış yazılmış bir anahtarda yeni bir dal kurar: `$a['notlr']['mat'] = 90` hata vermez, yanında yeni bir `notlr` dalı açar. Bu ders o dalın sonradan kim tarafından okunduğunu izlemez; ölçülen yalnız yazma anında hiçbir kanaldan haber gelmediğidir.

## Özet

- Çok boyutlu dizi ayrı bir tip değil, elemanları dizi olan dizidir; erişim yol boyunca anahtarların sırayla uygulanmasıdır.
- `count` yalnız dış düzeyi sayar; `COUNT_RECURSIVE` iç dizileri hem eleman hem içerik olarak sayar.
- Eksik iç anahtar `null` döndürür ve `E_WARNING` bildirir; bu dersin ölçü sınıfı **uyarı**dır (`eksik ic anahtar`).
- `null` üzerinde dizi erişimi de `E_WARNING` verir ve `null` döner; kopukluktan sonraki her halka sessizce `null` üretir.
- `??` yolun tamamını sessize çevirir; yanlış yazılmış yolu da aynı sessizlikle örter.
- Okuma ile yazma ayrı kanaldır: eksik yoldan okumak uyarı verir, boş diziye derin yazmak iç diziyi sessizce kurar.

## Sonraki Adım

Bu ders bir yolun kopukluğunu `null` ve uyarı olarak ölçtü. Dizi Fonksiyonları dersinde kanal değişiyor: bir eleman aramak, bulunamadığında uyarı vermiyor, bir değer dönüyor; ve o değer, bulunan ilk elemanın dönüşüyle gevşek karşılaştırmada karışabiliyor.
