PHP json_decode () geçerli JSON ile NULL döndürür?


104

Bir düz metin dosyasında depolanan bu JSON nesnesine sahibim:

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

Kodunu çözmeye çalıştığımda json_decode()NULL döndürüyor. Neden? Dosya okunabilir (yankılamayı denedim file_get_contents()ve iyi çalıştı).

JSON'u http://jsonlint.com/ ile test ettim ve tamamen geçerli.

Burada sorun ne?

Çözüm

Google'da cevaplar arıyorum, SO'ya geri döndüm: json_decode webservice çağrısından sonra NULL döndürüyor . JSON dosyam UTF BOM dizisine sahipti (orada olmaması gereken bazı ikili karakterler), bu nedenle JSON yapısını bozdu. Hex Editor'a gittim, baytları sildi. Her şey normale döndü. Bu neden oldu? Çünkü dosyayı Microsoft Windows'un Not Defteri'ni kullanarak düzenledim. Korkunç fikir!


5
PHP 5.2.9 ile çalışmak; bu yüzden kullanamıyorum json_last_error().
Joel A. Villarreal Bertoldi

1
Ayrıca dosyanın ortasındaki diğer geçersiz karakterlerde de bunun olabileceğini unutmayın. Az önce json_decode () null döndürüyordu çünkü dize muhtemelen MS Word'den yapıştırılmış ve sonra yanlış kodlanmış bu özel en-tirelerden birini içeriyordu. Olası sorunlu karakterleri belirlemek için JSON dosyasını açın (Notepad ++ 'da kullandım), kodlamayı değiştirin (dönüştürmeden) ve bir kopya olarak kaydedin. Sonra iki dosyayı ayırın (WinMerge kullandım).
LinusR

(Windows Not Defteri sorunu) Lütfen buna bakın, sorunu ben de paylaştım ve çözdü: stackoverflow.com/questions/10290849/…
Felix Aballi


Benim için özel bir şey değildi, sadece bir nesnenin elemanının sonunda fazladan bir virgül. Take away: JSON'nuzu tutarsız kılan her şey bir hata verecektir. Bonus ipucu: jsonviewer.stack.hu'ya güvenmeyin jsonlint gibi bir şey kullanın
Aman Alam

Yanıtlar:


68

Özel karakterlerin kodlaması olabilir. Kesin bilgi almak için json_last_error () isteyebilirsiniz .

Güncelleme: Sorun çözüldü, sorudaki "Çözüm" paragrafına bakın.


Uygulamaya başladığımdan beri özel karakterleri kullanıyorum ve daha önce herhangi bir sorun yaşamadım. Yerel olarak, JSON kod çözme mükemmel çalışıyor. Benim sunucumda yok. Ve json_last_error()arayamıyorum çünkü PHP 5.2.9. Bu işlev PHP 5.3.0'da görünür.
Joel A. Villarreal Bertoldi

1
Hayır, bu işe yaramalı. Şu anda daha fazla test yapamam, daha sonra ulaşırsam buraya göndereceğim. Ayrıca, kullanıcının katkıda bulunduğu notlarda da birkaç ipucu vardır: de.php.net/json_decode belki bir şey yardımcı olabilir.
Pekka

1
Benim için PHP 5.3'te, metin UTF-8'de kodlandığında iyi çalışıyor. İçinden metin geçmek Ama eğer utf8_decode(), sonra json_decode()sessizce başarısız olur.
Matthew

1
@Pekka Google'da cevaplar arıyorum, SO'ya geri döndüm: stackoverflow.com/questions/689185/json-decode-returns-null-php . JSON dosyam UTF BOM dizisine sahipti (orada olmaması gereken bazı ikili karakterler), bu nedenle JSON yapısını bozdu. Hex Editor'a gittim, baytları sildi. Her şey normale döndü. Bu neden oldu? Çünkü dosyayı Micro $ oft Windows 'Not Defteri kullanarak düzenledim. Korkunç fikir!
Joel A. Villarreal Bertoldi

2
Bu, PHP çalışanlarına bir hata olarak bildirilmelidir. BOM geçerli UTF8 ise, sessizce boğulmamalıdır.
jmucchiello

86

Bu benim için çalıştı

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );

2
Bunu kullandım ve diziyi aldım ama dile özgü karakterlerim (ş, ç, ö, ..) da silindi.
zkanoca

5
Json verileri UTF-8 kodluysa (veya tahmin ettiğim herhangi bir UTF kodlaması) bu doğru değildir. Geçerli UTF-8 kodlu verileri kaldıracaktır. Dosya sadece ingilizce içerdiği sürece muhtemelen çalışacaktır, ancak bu her zaman riskli bir varsayımdır. Ben bunu kullanmazdım.
DaedalusAlpha

Bununla işe yarıyor ama onsuz olmuyor, iki tel aynı olsa bile, bir şeyi mi kaçırıyorum?
Rudie Visser

çalışıyor! ama neden? kodunu çözmeye çalıştığım dizede özel bir karakter yoktu
Tobias Gassmann

Harika. Benim için çalıştı. :)
Sohil

31

Onunla deneyebilirsin.

json_decode(stripslashes($_POST['data']))

Yanlışlıkla stripslashes()iki kez aradım , bu da temel eğik çizgileri kaldırdı ve geçersiz JSON dizesine neden oldu. Bu cevap hatayı
Philipp

22

İsteği Chrome'da kontrol ederseniz, JSON'un metin olduğunu görürsünüz, bu nedenle JSON'a boş kod eklenmiştir.

Kullanarak temizleyebilirsiniz

$k=preg_replace('/\s+/', '',$k);

O zaman şunları kullanabilirsiniz:

json_decode($k)

print_r diziyi gösterecektir.


Bunun için teşekkürler - umarım eksik İngilizceni bulursun.
Dean_Wilson

Adamım sen efsanesin, bütün gün bununla uğraşıyorsun.
Sboniso Marcus Nzimande

Benim için yaptım !! Yaptığım basit bir ince ayar, yerine bir boşluk eklemek, bunu kullanıyorum ve benim alanımın da yerini alıyor gibi görünüyor. şimdi iyi çalışıyor. $k=preg_replace('/\s+/', ' ',$k);
Kash

Sorun şu ki, bu her bir boşluğu kaldırıyor, İngilizce metni birbirine yapıştırıyor değil mi?
CodeGuru

14

Ben de aynı sorunu yaşadım ve kodu çözmeden önce tırnak karakterini değiştirerek çözdüm.

$json = str_replace('"', '"', $json);
$object = json_decode($json);

JSON değerim JSON.stringify işlevi tarafından oluşturuldu.


Bu durumda muhtemelen htmlspecialchars işlevi kullanılmaktadır ve JSON artık ayrıştırılamaz. Bunu tersine çevirmek için, & quot;
Davy

12

Belki bazı gizli karakterler json'unuzla uğraşıyor, şunu deneyin:

$json = utf8_encode($yourString);
$data = json_decode($json);

Yukarıdaki tüm çözümleri denedikten sonra, bu nihayet benim için çalıştı. Çok teşekkürler !!
Anis R.

7
$k=preg_replace('/\s+/', '',$k); 

benim için yaptı. Ve evet, Chrome'da test etmek. Kullanıcı için Thx2254008


4

Bugün bu sorunla karşılaştığım için bunu ekleyeceğimi düşündüm. JSON dizenizi çevreleyen herhangi bir dize dolgusu varsa, json_decode NULL döndürür.

JSON'u PHP değişkeni dışında bir kaynaktan çekiyorsanız, önce onu "kırpmanız" akıllıca olacaktır:

$jsonData = trim($jsonData);

4

bu, hata türünün ne olduğunu anlamanıza yardımcı olur

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

2

Sadece biraz zaman ayırın. Bunun sadece html kodlama sorunu olduğunu bulmak için 3 saat harcadım. Bunu dene

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$json_errors = array(
JSON_ERROR_NONE => 'No error has occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
);
echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
print_r($param);

1

Jürgen Math'ın belirttiği gibi user2254008 tarafından listelenen preg_replace yöntemini kullanarak benim için de düzeltildi.

Bu, Chrome ile sınırlı değil, bir karakter seti dönüştürme sorunu gibi görünüyor (en azından benim durumumda, Unicode -> UTF8) Bu, sahip olduğum tüm sorunları düzeltti.

Gelecekteki bir düğüm olarak, kod çözmekte olduğu JSON Nesnesi i Python'un json.dumps işlevinden geldi. Bu da diğer bazı sağlıksız verilerin kolayca ele alınmasına rağmen bunları yaymasına neden oldu.


1

Veritabanından json alıyorsanız,

mysqli_set_charset($con, "utf8");

$ con bağlantı bağlantısını tanımladıktan sonra


Teşekkürler TomoMiha. Özel karakterler içeren MySQL ile ilgili tüm problemlerime tam olarak uyan şey budur ve json_decode ile dönüştürüldüğünde, bu belirli alan = null ....
KLL


1

Benim durumum için, JSON dizesindeki tek alıntı yüzünden.

JSON biçimi yalnızca anahtarlar ve dize değerleri için çift tırnak kabul eder.

Misal:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

Javascript sözdizimi yüzünden bunu karıştırdım. Javascript'te elbette şunu yapabiliriz:

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

ancak daha sonra bu nesneleri JSON dizesine dönüştürdüğünüzde:

JSON.stringify(json); // "{"hello":"PHP"}"

0

JSON'u yazdırıp ardından sayfa kaynağını (CTRL / CMD + U) kontrol ederek bu sorunu çözdüm:

print_r(file_get_contents($url));

Takip eden bir <pre>etiket olduğu ortaya çıktı.


0

bu noktaları sağlamalısın

1. json dizenizde bilinmeyen karakterler yok

2. json dizesi, çevrimiçi json görüntüleyiciden görüntüleyebilir (google'da çevrimiçi görüntüleyici veya json için ayrıştırıcı olarak arama yapabilirsiniz), hatasız görüntülemesi gerekir

3. dizenizde html varlıkları yok, düz metin / dizge olmalıdır

3. noktanın açıklaması için

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

to (htmlentities () işlevini kaldır)

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

0

Benim için, json_decode () düzgün çalışmasını sağlamak için error_reporting'i kapatmak zorunda kaldım . Garip geliyor ama benim durumum için doğru. Çünkü çözmeye çalıştığım JSON dizesi arasında bazı uyarılar var.


0

JSON verilerinden geçerli olan bir NULL sonucu aldığınızda hatırlanması gereken en önemli şey aşağıdaki komutu kullanmaktır:

json_last_error_msg();

Yani.

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

Daha sonra bunu şu şekilde düzeltirsiniz:

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

0

Yani, html_entity_decode () benim için çalıştı. Lütfen bunu deneyin.

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

-5
<?php 
$json_url = "http://api.testmagazine.com/test.php?type=menu";
$json = file_get_contents($json_url);
$json=str_replace('},

]',"}

]",$json);
$data = json_decode($json);

echo "<pre>";
print_r($data);
echo "</pre>";
?>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.