---
title: 'Dizgi İşleme'
source: 'https://academia.sh/tr/kurslar/php-temelleri/dizgi-isleme'
course: 'PHP Temelleri'
language: tr
updated: '2026-10-21T05:03:33+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'sprintf ile sayı ve dizgi biçimlendirir ve genişlik belirtecinin baytla çalıştığını ölçer'
    - "Bozuk JSON'un json_decode'dan null döndürdüğünü ölçer ve dönüş sınıfına yazar"
    - "json_last_error ve JSON_THROW_ON_ERROR ile geçerli null'u bozuk girdiden ayırır"
---

# Dizgi İşleme

sprintf ve printf ile biçimlendirme; strlen ile mb_strlen arasındaki bayt ve karakter ayrımı; bozuk JSON'un json_decode'dan null olarak dönmesi; json_last_error ve JSON_THROW_ON_ERROR ile ayrımın yapılması; implode ve strlen'in dizi argümanındaki davranışı.

Dizi Fonksiyonları dersi, dönüş kanalının ayrım gücünün çağıranın ayrım gücüyle sınırlı olduğunu gösterdi: `0` ile `false` ayırt edilmeyince bulunan ilk eleman "yok" sayıldı. Dizgi işlemede aynı sınır daha sert bir biçimde çıkıyor. Bir dizgi çözüldüğünde dönen `null`, hem geçerli bir `null` değerinden hem bozuk girdiden gelebiliyor ve değerin kendisi hangisinin olduğunu söylemiyor.

Dizgi (string) PHP'de bayt dizisidir; bir karakterin kaç bayt tuttuğu dizgiyi okuyan fonksiyona bağlıdır. Ders iki konu işliyor: dizgiyi biçimlendiren ve ölçen fonksiyonlar, ve dizgiyi JSON olarak kodlayıp çözen fonksiyonlar. Sınıf adları önceki derslerdeki anlamıyla kullanılır: **sessiz**, **dönüş**, **uyarı**, **durdurur**.

## Biçimlendirme ve Bayt Ölçümü

`sprintf` bir biçim dizgisine göre değerleri yerleştirir; `printf` aynı biçimlendirmeyi doğrudan yazdırır. Genişlik, hizalama ve ondalık hane sayısı belirteçle verilir.

```php
<?php
// bicim.php — sprintf ile bicimlendirme
echo sprintf('%05d', 42), "\n";
echo sprintf('%.2f', 3.14159), "\n";
echo sprintf('%-8s|', 'php'), "\n";
echo sprintf('%8s|', 'php'), "\n";
echo sprintf('%s kitap, %d sayfa', 'Ders', 120), "\n";
printf("%x %o %b\n", 255, 8, 5);
echo sprintf('%1$s-%2$s-%1$s', 'a', 'b'), "\n";
```

```
00042
3.14
php     |
     php|
Ders kitap, 120 sayfa
ff 10 101
a-b-a
```

Genişlik belirteci karakter değil bayt sayar. Çok baytlı bir harf içeren dizgide bu fark görünür; aşağıdaki dosya yalnız uzunlukları basıyor, hizalı bir sütun kurmuyor.

```php
<?php
// bayt.php — strlen bayt, mb_strlen karakter sayar
$ad = 'señor';

echo 'strlen: ', strlen($ad), "\n";
echo 'mb_strlen: ', mb_strlen($ad), "\n";

$dolgulu = sprintf('%-8s', $ad);
echo 'dolgulu bayt: ', strlen($dolgulu), "\n";
echo 'dolgulu karakter: ', mb_strlen($dolgulu), "\n";

echo 'ascii strlen: ', strlen('senor'), "\n";
echo 'ascii mb_strlen: ', mb_strlen('senor'), "\n";
```

```
strlen: 6
mb_strlen: 5
dolgulu bayt: 8
dolgulu karakter: 7
ascii strlen: 5
ascii mb_strlen: 5
```

`strlen('señor')` altı, `mb_strlen('señor')` beş verdi: `ñ` iki bayttır ve tek karakterdir. `sprintf('%-8s')` ile sekiz bayta doldurulan dizgi yalnız yedi karakter genişliğinde görünür; hizalı bir sütunda bu kayma bir sonraki sütunu sola çeker. Tamamen ASCII olan `senor` için iki fonksiyon aynı sayıyı verir, bu yüzden fark yalnız çok baytlı veri geldiğinde ortaya çıkar. Sorun hiçbir kanaldan haber vermez: **sessiz**. Çok baytlı harf barındıran veri hizalı bir sütuna konmadan önce genişlik bayt değil karakter üzerinden hesaplanmalıdır.

**DZ13.** Bu ders `mb_` ailesinin yalnız `mb_strlen`'ini kullanır ve girdinin tek bir kodlamada (UTF-8) olduğunu varsayar. Kodlamanın belirtilmediği ya da karışık olduğu girdi bu dersin dışındadır ve ölçülmez.

## Bozuk JSON

JSON, dizileri ve ilişkisel dizileri metne çeviren bir değiş tokuş biçimidir. `json_encode` PHP değerini, `json_decode` metni PHP değerine çevirir. İkisi de başarısız olduğunda ne yaptığını dinleyici sınıflıyor; `kanal.php` aşağıda tam metniyle veriliyor ve çı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
// json.php — json ve dizgi islemlerinde sorun kanallari
require 'kanal.php';

$gozlemler = [
    'bozuk json'        => fn() => json_decode('{bozuk'),
    'gecerli json'      => fn() => json_decode('{"a":1}', true),
    'bozuk kodlama'     => fn() => json_encode("\xB1"),
    'istisnali kodlama' => fn() => json_encode("\xB1", JSON_THROW_ON_ERROR),
    'ic ice implode'    => fn() => implode(',', [1, [2, 3]]),
    'dizi ile strlen'   => fn() => strlen([1, 2]),
];

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

```
bozuk json         donus    sonuc null
gecerli json       sessiz   sonuc dizi(1)
bozuk kodlama      donus    sonuc false
istisnali kodlama  durdurur JsonException
ic ice implode     uyari    E_WARNING, sonuc string 1,Array
dizi ile strlen    durdurur TypeError
```

İlk satır kursun `bozuk json` gözlemidir: `json_decode('{bozuk')` `null` döndürdü, hiçbir seviye bildirilmedi. Sınıf **dönüş**. Üçüncü satır aynı kanalın kodlama yönü: geçersiz bir bayt dizisini kodlamak `false` döndürür. İkisi de bir hata olduğunu yalnız dönüş değeriyle söyler.

Dördüncü satır kanalın değiştiğini gösteriyor. `JSON_THROW_ON_ERROR` bayrağı verildiğinde aynı sorun `JsonException` olarak fırlar; sınıf **durdurur**. Bayrak, dönüş kanalındaki bir sorunu istisna kanalına taşır ve çağırana kontrolü bırakır: yakalamazsa yürütme durur. Beşinci satır dizgi işlemenin üçüncü kanalı: iç içe dizi `implode` edildiğinde iç dizi `'Array'` dizgisine çevrilir ve `E_WARNING` bildirilir, yani **uyarı**. Sonuncusu tip kanalıdır: `strlen` bir dizi argümanıyla çağrıldığında `TypeError` fırlatır ve durdurur.

## Metin Arama ve Kesme

Dizgi içinde arama yapan `strpos`, aranan başlangıçta bulunduğunda `0`, hiç bulunamadığında `false` döndürür. Dizi Fonksiyonları dersindeki `array_search` ile aynı kanal ve aynı tuzak: gevşek karşılaştırma ikisini ayırt etmez. PHP bu iş için dönüş değerine bakmayı gerektirmeyen `str_contains` fonksiyonunu sunar.

```php
<?php
// arama.php — dizgi arama ve kesme islevleri
$metin = 'php dersi';

echo 'strpos basta: ', var_export(strpos($metin, 'php'), true), "\n";
echo 'strpos yok: ', var_export(strpos($metin, 'js'), true), "\n";
echo 'gevsek basta: ', (strpos($metin, 'php') == false ? 'bulunamadi' : 'bulundu'), "\n";
echo 'str_contains basta: ', var_export(str_contains($metin, 'php'), true), "\n";
echo 'substr: ', var_export(substr($metin, 4), true), "\n";
echo 'substr uzak: ', var_export(substr($metin, 20), true), "\n";
echo 'explode: ', json_encode(explode(' ', $metin)), "\n";
echo 'bos ayirici: ', json_encode(explode(',', '')), "\n";
echo 'trim: ', var_export(trim("  a b \n"), true), "\n";
echo 'str_replace: ', str_replace('php', 'go', $metin), "\n";
```

```
strpos basta: 0
strpos yok: false
gevsek basta: bulunamadi
str_contains basta: true
substr: 'dersi'
substr uzak: ''
explode: ["php","dersi"]
bos ayirici: [""]
trim: 'a b'
str_replace: go dersi
```

`strpos` başta bulunan aranan için `0` döndürdü ve gevşek karşılaştırma bunu `bulunamadi` saydı; `str_contains` aynı soruyu `true` ile doğru yanıtladı. `substr` başlangıç dizgi sınırının ötesindeyse boş dizgi döndürür, hata vermez. `explode` boş bir dizgiyi ayırdığında boş liste değil, tek boş dizgili bir liste verir: tek elemanlı `[""]`. Bu sonuç bir sınır koşuludur ve "veri yok" ile "boş veri var" ayrımını sessizce siler.

**DZ14.** `str_contains`, `str_starts_with` ve benzerleri sorunu kanal olarak çözmez; yalnız soruyu doğru tipe çevirir. Kullanım rehberi yazmak bu dersin işi değildir ve yukarıdaki tabloda yer almayan davranışlar için bir iddia kurulmaz.

Çok baytlı bir harfi bayt düzeyinde kesen fonksiyon, geçersiz bir dizgi üretir ve bu dizgi bir sonraki kodlama çağrısında sorun çıkarır. Büyük harfe çevirme de aynı bayt/karakter ayrımına bağlıdır.

```php
<?php
// kes.php — bayt duzeyinde kesmenin ve buyutmenin sonucu
$ad = 'señor';

$bayt_kesik = substr($ad, 0, 3);
$karakter_kesik = mb_substr($ad, 0, 3);

echo 'bayt kesik uzunluk: ', strlen($bayt_kesik), "\n";
echo 'bayt kesik gecerli mi: ', var_export(mb_check_encoding($bayt_kesik, 'UTF-8'), true), "\n";
echo 'bayt kesik json: ', var_export(json_encode($bayt_kesik), true), "\n";
echo 'karakter kesik uzunluk: ', mb_strlen($karakter_kesik), "\n";
echo 'karakter kesik gecerli mi: ', var_export(mb_check_encoding($karakter_kesik, 'UTF-8'), true), "\n";
echo 'buyutme ayni mi: ', var_export(strtoupper($ad) === mb_strtoupper($ad), true), "\n";
```

```
bayt kesik uzunluk: 3
bayt kesik gecerli mi: false
bayt kesik json: false
karakter kesik uzunluk: 3
karakter kesik gecerli mi: true
buyutme ayni mi: false
```

`substr($ad, 0, 3)` üç bayt aldı ve `ñ` harfinin ilk baytını kesip bıraktı; sonuç geçerli bir UTF-8 dizgisi değil ve `json_encode` onu `false` döndürerek reddetti. `mb_substr` aynı kesimi karakter sınırında yaptı ve sonuç geçerli kaldı. `strtoupper` yalnız ASCII harflerini büyütür; `mb_strtoupper` çok baytlı harfi de dönüştürür, bu yüzden iki sonuç eşit çıkmadı. Kesme ve büyütme fonksiyonunun bayt ile karakter arasındaki seçimi sorunu hiçbir kanaldan duyurmaz: kesik dizgi ancak sonradan, kodlama aşamasında dönüş değeriyle fark edilir.

## Biçim Belirteçlerinin Sınırı

`sprintf` biçim dizgisindeki belirteçlerle argümanları eşler; belirteç sayısı, tipi ve sözdizimi çağrının kanalını belirler.

```php
<?php
// belirtec.php — sprintf belirteclerinin sinirlari
require 'kanal.php';

$gozlemler = [
    'genislik ve duyarlik' => fn() => sprintf('%05.1f|%-4s|', 3.14159, 'ab'),
    'dolgu karakteri'      => fn() => sprintf("%'*8s", 'php'),
    'isaretli sayi'        => fn() => sprintf('%+d', 5),
    'dizgi sayi olarak'    => fn() => sprintf('%d', 'abc'),
    'eksik arguman'        => fn() => sprintf('%s %s', 'a'),
    'bilinmeyen belirtec'  => fn() => sprintf('%y', 1),
];

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

```
genislik ve duyarlik sessiz   sonuc string 003.1|ab  |
dolgu karakteri      sessiz   sonuc string *****php
isaretli sayi        sessiz   sonuc string +5
dizgi sayi olarak    sessiz   sonuc string 0
eksik arguman        durdurur ArgumentCountError
bilinmeyen belirtec  durdurur ValueError
```

İlk üç satır belirteçlerin normal çalışmasını gösteriyor ve sessizdir. Dördüncü satır asıl noktadır: `%d` belirteci sayısal olmayan bir dizgiyi `0`'a çevirir ve hiçbir seviye bildirmez; yanlış tipte veri biçimlendirmede sessizce kaybolur. Argüman sayısı belirteç sayısından az olduğunda `ArgumentCountError`, tanımsız bir belirteç yazıldığında `ValueError` fırlar; ikisi de **durdurur**. Aynı fonksiyon, bir hata sınıfında sessiz, bir başkasında durdurucu davranıyor: kanal çağrının hatasının türüne bağlıdır.

## Doldurma, Sayı Biçimi ve Karşılaştırma

Sayıların ve dizgilerin görüntülenmesi için kullanılan birkaç yardımcı fonksiyon, hizalama ve ayırıcı gibi ayrıntıları argümanlara taşır.

```php
<?php
// yardimci.php — doldurma, sayi bicimi ve dizgi karsilastirma
require 'kanal.php';

echo number_format(1234567.891, 2, ',', '.'), "\n";
echo number_format(0.5), ' ', number_format(1.5), ' ', number_format(2.5), "\n";
echo str_pad('7', 3, '0', STR_PAD_LEFT), "|", str_pad('ab', 6, '-', STR_PAD_BOTH), "|\n";
echo ucwords('php dizgi isleme'), "\n";
echo strrev('abc'), ' ', str_word_count('bir iki uc'), "\n";
echo 'strcmp: ', strcmp('a', 'b'), ' ', strcmp('b', 'a'), ' ', strcmp('a', 'a'), "\n";
echo 'spaceship: ', 'a' <=> 'b', ' ', 'b' <=> 'a', ' ', 'a' <=> 'a', "\n";

$gozlemler = [
    'sayisal dizgi esit' => fn() => '10' == '1e1',
    'sayisal dizgi kati' => fn() => '10' === '1e1',
    'baslangic sayisal'  => fn() => '12abc' + 1,
    'tam sayisal degil'  => fn() => 'abc' + 1,
    'sayiya cevirme'     => fn() => (int) '12abc',
];

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

```
1.234.567,89
1 2 3
007|--ab--|
Php Dizgi Isleme
cba 3
strcmp: -1 1 0
spaceship: -1 1 0
sayisal dizgi esit  sessiz   sonuc true
sayisal dizgi kati  donus    sonuc false
baslangic sayisal   uyari    E_WARNING, sonuc int 13
tam sayisal degil   durdurur TypeError
sayiya cevirme      sessiz   sonuc int 12
```

`number_format` ondalıkta yuvarlar (`0.5`, `1.5`, `2.5` için `1 2 3`) ve binlik ile ondalık ayırıcısı argümanlarla belirlenir. `str_pad` sol, sağ ya da iki yandan doldurur. `strcmp` ve `<=>` sıralama için aynı üç değeri verir.

Karşılaştırmada asıl dikkat edilecek nokta sayısal dizgilerdir: `'10' == '1e1'` doğrudur, çünkü iki taraf da sayıya çevrilir; `===` ise yanlış verir. `'12abc' + 1` 13 üretir ama `E_WARNING` verir, `'abc' + 1` ise `TypeError` ile durur. `(int) '12abc'` sessizce 12 verir; aynı girdi için dönüştürme sessiz, aritmetik uyarılı, tam sayısal olmayan dizgide aritmetik durdurucudur.

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

Dönüş kanalı ayırt edemez. Geçerli `null` değerinin çözümü ile bozuk girdinin çözümü aynı değeri verir.

```php
<?php
// ayirt.php — null geri donusu iki ayri durumdan gelebilir
$bozuk = json_decode('{bozuk');
echo 'bozuk: ', var_export($bozuk, true), ' hata ', json_last_error(), "\n";

$gecerli = json_decode('null');
echo 'gecerli null: ', var_export($gecerli, true), ' hata ', json_last_error(), "\n";

echo 'esit mi: ', var_export($bozuk === $gecerli, true), "\n";
echo 'hata adi: ', json_last_error() === JSON_ERROR_NONE ? 'yok' : 'var', "\n";

try {
    json_decode('{bozuk', false, 512, JSON_THROW_ON_ERROR);
    echo "bozuk: firlatmadi\n";
} catch (JsonException $e) {
    echo 'bozuk: ', get_class($e), ' kod ', $e->getCode(), "\n";
}

$sonuc = json_decode('null', false, 512, JSON_THROW_ON_ERROR);
echo 'gecerli null, bayrakli: ', var_export($sonuc, true), "\n";
```

```
bozuk: NULL hata 4
gecerli null: NULL hata 0
esit mi: true
hata adi: yok
bozuk: JsonException kod 4
gecerli null, bayrakli: NULL
```

İki çağrı da `null` döndürdü ve `===` ile eşit çıktılar. Ayrımı `json_last_error()` yapıyor: bozuk girdide dört (`JSON_ERROR_SYNTAX`), geçerli `null`'da sıfır. Bu fonksiyon son çağrının hata durumunu taşır; bir sonraki `json_decode` çağrısı onu sıfırlar, bu yüzden hemen ardından okunması gerekir. Daha sağlam yol `JSON_THROW_ON_ERROR` bayrağıdır: bozuk girdi `JsonException` fırlatır, geçerli `null` ise `null` olarak döner ve iki durum artık ayrı kanallardan gelir.

**DZ15.** `json_last_error()` genel bir hata durumunu tutar ve ders onu yalnız `json_decode` çağrısının hemen ardından okur. Başka bir fonksiyonun araya girdiği durumlar ölçülmez. Ders hiçbir ini değerine güvenmez; `JSON_THROW_ON_ERROR` bayrağı çağrıya açıkça verilir.

## Özet

- `sprintf` ve `printf` biçim dizgisine göre değer yerleştirir; genişlik belirteci karakter değil bayt sayar.
- `strlen('señor')` altı, `mb_strlen('señor')` beş verir; çok baytlı harf barındıran veri hizalı sütuna konmadan önce genişlik karakterle hesaplanmalıdır.
- `json_decode('{bozuk')` `null` döndürür; bu dersin ölçü sınıfı **dönüş**tür (`bozuk json`). Geçersiz bayt dizisi için `json_encode` `false` döndürür.
- `JSON_THROW_ON_ERROR` aynı sorunu `JsonException` olarak fırlatır; sınıf **durdurur**.
- Geçerli `null` ile bozuk JSON ikisi de `null` döndürür; ayrımı `json_last_error()` (sıfır ya da dört) ya da `JSON_THROW_ON_ERROR` yapar.
- İç içe dizinin `implode`'u `'Array'` ve `E_WARNING` verir; dizi argümanıyla `strlen` `TypeError` fırlatır.

## Sonraki Adım

Dizilerin ve dizgilerin sorunları dört kanaldan duyulabiliyor: sessiz, dönüş, uyarı ve durdurur. Sıradaki konu, verinin kodun içinden değil, dışarıdan geldiği yerdir. Süper Küresel Değişkenler dersi, istek verisi eksik olduğunda hangi kanaldan ne duyulduğunu ölçüyor.
