Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 6 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi

PHP ile JSON kodlarken karakter sorunları nasıl giderilir?​


PHP ile JSON kodlarken karakter sorunu yaşıyorsanız önce verinin geçerli UTF-8 olup olmadığını kontrol edin. json_encode() yalnızca geçerli UTF-8 metinleri güvenilir biçimde JSON'a dönüştürür. Kodlama başarısız olursa hatayı yakalayın; veriyi sessizce yok saymak yerine bozuk baytın geldiği kaynağı düzeltin. Geçici ve kontrollü bir tolerans gerekiyorsa JSON_INVALID_UTF8_SUBSTITUTE kullanabilirsiniz. JSON_UNESCAPED_UNICODE ise yalnızca geçerli Unicode karakterlerinin JSON içinde nasıl gösterileceğini değiştirir; geçersiz UTF-8'i onarmaz.

Sorun nasıl oluşur?​


PHP dizisindeki metinler byte dizileri olarak tutulur. JSON kodlayıcı, bu byte'ların geçerli UTF-8 karakterlerine karşılık gelmesini bekler. Örneğin UTF-8'de iki byte ile başlayan fakat ikinci byte'ı uygun olmayan bir metin, ekranda her zaman belirgin görünmeyebilir; ancak json_encode() bunu geçersiz UTF-8 olarak reddedebilir.

Örneği UTF-8 kaydedilmiş bir dosyada PHP 7.3 veya üzeri CLI ile çalıştırabilirsiniz. Ekrandaki açıklama satırları nedeniyle bu bir JSON API yanıtı değildir. Aşağıdaki örnekte \xC3\x28 kasıtlı olarak bozuk bir byte dizisi üretir. İlk kodlama katı davranır ve hatayı istisna olarak bildirir. İkinci kodlama, sorunlu bölümü Unicode yenileme karakteriyle değiştirerek JSON üretir:

Kod:
<?php

$veri = [
    'mesaj' => 'Merhaba',
    'emoji' => '😀',
    'bozuk' => "Geçerli metin " . "\xC3\x28",
];

try {
    $json = json_encode(
        $veri,
        JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE
    );

    echo "Katı sonuç:\n" . $json . PHP_EOL;
} catch (JsonException $e) {
    echo "Katı kodlama başarısız: " . $e->getMessage() . PHP_EOL;
}

try {
    $json = json_encode(
        $veri,
        JSON_THROW_ON_ERROR |
        JSON_UNESCAPED_UNICODE |
        JSON_INVALID_UTF8_SUBSTITUTE
    );

    echo "Toleranslı sonuç:\n" . $json . PHP_EOL;
} catch (JsonException $e) {
    echo "Toleranslı kodlama da başarısız: " . $e->getMessage() . PHP_EOL;
}

Katı bölümde beklenen sonuç, JSON'un üretilmemesi ve geçersiz UTF-8 hatasının yazdırılmasıdır. Toleranslı bölümde JSON üretilir; bozuk bölüm genellikle � karakteriyle değiştirilir. Bu çıktı verinin başarıyla kurtarıldığı anlamına gelmez: özgün karakter veya byte kaybolmuştur. Kalıcı çözüm, bozuk değerin üretildiği veya okunduğu kaynağı düzeltmektir.

Hata yönetimini doğru kurma​


JSON_THROW_ON_ERROR kullanıldığında kodlama başarısızlığı JsonException olarak yakalanabilir. Bu yaklaşım, false dönen sonucu gözden kaçırma riskini azaltır. İstisna kullanmıyorsanız sonucu mutlaka kontrol edin:

Kod:
$json = json_encode($veri, JSON_UNESCAPED_UNICODE);

if ($json === false) {
    throw new RuntimeException(
        'JSON kodlama hatası: ' . json_last_error_msg()
    );
}

json_last_error_msg() yalnızca hatanın açıklamasını verir; bozuk karakterin hangi alan ve hangi byte konumunda olduğunu her zaman göstermez. Bu nedenle büyük bir payload yerine alanları izole ederek kaynağı daraltın. Veritabanından, dosyadan veya harici servisten gelen metni JSON kodlamadan önce incelemek daha etkilidir.

Hangi seçeneği kullanmalısınız?​


Aşağıdaki karar, verinin iş açısından ne kadar önemli olduğuna göre verilmelidir:

DurumTercihSonuç
Kimlik, fiyat, adres veya kayıt verisiKatı kodlama ve hata yakalamaBozuk veri sessizce gönderilmez; kaynak düzeltilir
Log, önizleme veya kaybı kabul edilen metinJSON_INVALID_UTF8_SUBSTITUTEBozuk bölüm yenileme karakteriyle değiştirilerek JSON üretilir
Sorunlu karakterleri tamamen atmakJSON_INVALID_UTF8_IGNOREVeri kaybı olur; yalnızca bunun kabul edildiği durumlarda kullanılmalıdır

JSON_INVALID_UTF8_IGNORE geçersiz byte'ları yok sayar. Bu seçenek hatayı gizleyebileceği ve metnin anlamını değiştirebileceği için genel çözüm değildir. JSON_INVALID_UTF8_SUBSTITUTE daha görünür bir kayıp bırakır; yine de asıl veri kaynağının düzeltilmesi gerekir.

Uygulanabilir teşhis adımları​


  1. Önce JSON_THROW_ON_ERROR ile kodlamayı çalıştırın ve gerçek istisna mesajını kaydedin.
  2. Payload'u alanlarına ayırarak hatalı alanı bulun. Tüm diziyi tek seferde kodlamak yerine şüpheli metin alanlarını sırayla test edin.
  3. Hatalı alanın nereden geldiğini belirleyin: dosya okuma, veritabanı sonucu, form verisi veya harici API yanıtı.
  4. Kaynağın UTF-8 olarak üretildiğini ve uygulama içinde metnin başka bir karakter setine yanlış dönüştürülmediğini kontrol edin. Bir metni rastgele utf8_encode() benzeri dönüşümlerden geçirmek sorunu çözmeyebilir, hatta geçerli veriyi bozabilir.
  5. Veri kaynağı hemen düzeltilemiyorsa yalnızca kaybın kabul edildiği akışta JSON_INVALID_UTF8_SUBSTITUTE kullanın ve bu durumu ayrıca loglayın.
  6. API yanıtında önce JSON metnini üretin, sonra Content-Type: application/json başlığıyla yalnız JSON gönderin; açıklama, BOM veya hata çıktısı eklemeyin. JSON çıktısı üretildikten sonra istemciye gönderin; kodlama başarısızken boş, kısmi veya eski bir JSON değerini başarı gibi döndürmeyin.

Geçerli karakterlerin JSON içinde "é" veya "\u00e9" biçiminde görünmesi iki durumda da aynı karakteri temsil edebilir. JSON_UNESCAPED_UNICODE okunabilir çıktıyı tercih eder; bu seçeneğin olmaması karakterin bozulduğu anlamına gelmez. Tersine, bozuk UTF-8 byte'ları Unicode kaçışlarıyla sarmalamak onları geçerli veriye dönüştürmez.

Sık yapılan hatalar​


Hatanın yalnızca ekranda görünen karaktere bakılarak teşhis edilmesi: Bir metin tarayıcıda normal görünebilir, fakat içinde geçersiz byte bulunabilir. JSON kodlayıcının hata sonucunu esas alın.

Her hatada IGNORE kullanılması: Bu, kodlamayı başarılı gösterebilir ancak kullanıcı adının, açıklamanın veya başka bir alanın bir bölümünü sessizce silebilir.

Unicode kaçışını onarım sanmak: JSON_UNESCAPED_UNICODE ve \uXXXX gösterimi yalnızca JSON metin gösterimidir. Giriş byte'ları geçersizse önce veri kaynağı düzeltilmelidir.

Hata sonucunu kontrol etmeden çıktı göndermek: json_encode() başarısız olduğunda dönen değeri doğrudan HTTP yanıtına yazmak, geçersiz veya boş bir API yanıtı oluşturabilir.

Sık sorulan sorular​


JSON içinde \u00e7 görmek karakterin bozuk olduğunu mu gösterir?​


Hayır. Bu, geçerli bir Unicode karakterinin kaçış gösterimidir. Alıcı JSON'u doğru çözümlüyorsa \u00e7 ile doğrudan ç aynı karakteri temsil eder.

Bozuk UTF-8'i JSON kodlamadan önce nasıl bulurum?​


Şüpheli metni mb_check_encoding($metin, 'UTF-8') ile test edebilirsiniz; ancak bunun için ilgili PHP eklentisinin kullanılabilir olması gerekir. Son kararı yine json_encode() hata yönetimiyle verin ve kontrol başarısızsa kaynağı düzeltin.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic