PHP json_decode () mengembalikan NULL dengan JSON yang valid?


104

Saya memiliki objek JSON ini yang disimpan pada file teks biasa:

{
    "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"
    }
}

Ketika saya mencoba untuk memecahkan kode dengan json_decode(), itu mengembalikan NULL. Mengapa? File tersebut dapat dibaca (saya mencoba menggemakan file_get_contents()dan berfungsi dengan baik).

Saya telah menguji JSON terhadap http://jsonlint.com/ dan itu sangat valid.

Ada apa disini?

Larutan

Mencari jawaban di Google, saya kembali ke SO: json_decode mengembalikan NULL setelah panggilan layanan web . File JSON saya memiliki urutan UTF BOM (beberapa karakter biner yang seharusnya tidak ada), dengan demikian, merusak struktur JSON. Pergi ke Hex Editor, menghapus byte. Semuanya kembali normal. Mengapa ini terjadi? Karena saya mengedit file menggunakan Notepad Microsoft Windows. Ide yang buruk!


5
Bekerja dengan PHP 5.2.9; jadi, saya tidak bisa menggunakan json_last_error().
Joel A. Villarreal Bertoldi

1
Perhatikan juga ini dapat terjadi dengan karakter tidak valid lainnya di tengah file. Saya baru saja json_decode () mengembalikan null karena string tersebut berisi salah satu en-dash khusus, mungkin ditempelkan dari MS Word, dan mungkin salah dikodekan. Untuk mengidentifikasi karakter masalah potensial, buka file JSON (saya gunakan di Notepad ++), ubah pengkodean (tanpa mengonversi), dan simpan sebagai salinan. Kemudian diff dua file (saya menggunakan WinMerge).
LinusR

(Masalah Windows Notepad) Silakan, konsultasikan ini, saya juga berbagi masalah dan itu memperbaikinya: stackoverflow.com/questions/10290849/…
Felix Aballi


Bagi saya, itu bukanlah sesuatu yang istimewa, hanya sebuah koma tambahan di akhir elemen objek. Singkirkan: Apa pun yang membuat JSON Anda tidak konsisten, akan menimbulkan kesalahan. Tip bonus: jangan percaya jsonviewer.stack.hu Gunakan sesuatu seperti jsonlint
Aman Alam

Jawaban:


68

Bisa jadi pengkodean karakter khusus. Anda bisa meminta json_last_error () untuk mendapatkan informasi yang pasti.

Pembaruan: Masalah ini terpecahkan, lihat paragraf "Solusi" dalam pertanyaan.


Saya telah menggunakan karakter khusus sejak saya memulai aplikasi dan tidak ada masalah sebelumnya. Secara lokal, decoding JSON bekerja dengan sempurna. Di server saya, tidak. Dan saya tidak bisa menelepon json_last_error()karena itu PHP 5.2.9. Fungsi itu muncul di PHP 5.3.0.
Joel A. Villarreal Bertoldi

1
Nah, ini seharusnya berhasil. Saya tidak dapat melakukan lebih banyak pengujian sekarang, jika saya mendapatkannya nanti saya akan posting di sini. Ada juga beberapa petunjuk dalam catatan kontribusi pengguna: de.php.net/json_decode mungkin ada yang bisa membantu.
Pekka

1
Bagi saya, pada PHP 5.3, ini berfungsi dengan baik ketika teks dikodekan dalam UTF-8. Tetapi jika saya melewatkan teks utf8_decode()terlebih dahulu, kemudian json_decode()gagal secara diam-diam.
Matius

1
@Pekka Mencari jawaban di Google, saya kembali ke SO: stackoverflow.com/questions/689185/json-decode-returns-null-php . File JSON saya memiliki urutan UTF BOM (beberapa karakter biner yang seharusnya tidak ada), dengan demikian, merusak struktur JSON. Pergi ke Hex Editor, menghapus byte. Semuanya kembali normal. Mengapa ini terjadi? Karena saya mengedit file menggunakan Micro $ sering Notepad Windows. Ide yang buruk!
Joel A. Villarreal Bertoldi

2
Ini harus dilaporkan sebagai bug kepada orang-orang PHP. Jika BOM adalah UTF8 yang valid, BOM tidak boleh tersedak secara diam-diam.
jmucchiello

86

Ini berhasil untuk saya

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

2
Saya telah menggunakan ini dan mendapatkan lariknya tetapi karakter khusus bahasa saya (ş, ç, ö, ..) telah dihapus juga.
zkanoca

5
Ini tidak benar jika data json dikodekan UTF-8 (atau saya kira semua pengkodean UTF). Ini akan menghapus data berenkode UTF-8 yang valid. Ini mungkin akan berfungsi selama file hanya berisi bahasa Inggris, tetapi itu selalu merupakan asumsi yang berisiko. Saya tidak akan menggunakan ini.
DaedalusAlpha

Dengan ini ia berhasil tetapi tanpanya tidak, meskipun kedua string itu identik, apakah saya kehilangan sesuatu?
Rudie Visser

itu berhasil! tapi kenapa? string yang saya coba pecahkan kode tidak memiliki karakter khusus di dalamnya
Tobias Gassmann

Hebat. Bekerja untuk saya. :)
Sohil

31

Anda bisa mencobanya.

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

Saya tidak sengaja menelepon stripslashes()dua kali, yang menghapus garis miring penting dan menyebabkan string JSON tidak valid. Jawaban ini membantu saya menemukan kesalahannya
Philipp

22

Jika Anda memeriksa permintaan di chrome Anda akan melihat bahwa JSON adalah teks, jadi ada kode kosong yang ditambahkan ke JSON.

Anda dapat menghapusnya dengan menggunakan

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

Kemudian Anda dapat menggunakan:

json_decode($k)

print_r kemudian akan menampilkan array.


Terima kasih untuk ini - harap Anda menemukan bahasa Inggris Anda yang hilang.
Dean_Wilson

Astaga, kau adalah legenda, telah mempermasalahkan ini sepanjang hari.
Sboniso Marcus Nzimande

Apakah itu untukku !! Perubahan sederhana yang saya buat adalah menambahkan spasi di ganti, saya menggunakan ini, dan sepertinya juga mengganti spasi saya. bekerja dengan baik sekarang. $k=preg_replace('/\s+/', ' ',$k);
Kash

Masalahnya adalah, ini menghapus setiap spasi, membuat teks bahasa Inggris semuanya saling menempel bukan?
CodeGuru

14

Saya memiliki masalah yang sama dan saya menyelesaikannya hanya dengan mengganti karakter kutipan sebelum decode.

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

Nilai JSON saya dihasilkan oleh fungsi JSON.stringify.


Dalam hal ini fungsi htmlspecialchars mungkin telah digunakan dan JSON tidak dapat diurai lagi. Untuk membalikkannya ada fungsi "htmlspecialchars_decode" alih-alih mengganti & quot;
Davy

11

Mungkin beberapa karakter tersembunyi mengotak-atik json Anda, coba ini:

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

Setelah mencoba semua solusi di atas, yang ini akhirnya berhasil untuk saya. Terima kasih banyak!!
Anis R.

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

melakukannya untuk saya. Dan ya, menguji di Chrome. Terima kasih kepada pengguna2254008


4

Hanya berpikir saya akan menambahkan ini, karena saya mengalami masalah ini hari ini. Jika ada padding string yang mengelilingi string JSON Anda, json_decode akan mengembalikan NULL.

Jika Anda menarik JSON dari sumber selain variabel PHP, sebaiknya Anda "memangkas" terlebih dahulu:

$jsonData = trim($jsonData);

4

ini membantu Anda memahami apa jenis kesalahan

<?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

Hemat satu kali saja. Saya menghabiskan 3 jam untuk mengetahui bahwa itu hanya masalah encoding html. Coba ini

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

Seperti yang dinyatakan oleh Jürgen Math menggunakan metode preg_replace yang terdaftar oleh user2254008 memperbaikinya untuk saya juga.

Ini tidak terbatas pada Chrome, tampaknya menjadi masalah konversi kumpulan karakter (setidaknya dalam kasus saya, Unicode -> UTF8) Ini memperbaiki semua masalah yang saya alami.

Sebagai node masa depan, Objek JSON yang saya dekode berasal dari fungsi json.dumps Python. Hal ini pada gilirannya menyebabkan beberapa data tidak sehat lainnya disebarluaskan meskipun mudah ditangani.


1

Jika Anda mendapatkan json dari database, letakkan

mysqli_set_charset($con, "utf8");

setelah menentukan tautan koneksi $ con


Terima kasih TomoMiha. Inilah yang cocok dengan semua masalah saya dengan MySQL yang berisi karakter khusus dan ketika diubah oleh json_decode, bidang tertentu itu dihasilkan = null ....
KLL


1

Untuk kasus saya, ini karena kutipan tunggal dalam string JSON.

Format JSON hanya menerima tanda kutip ganda untuk kunci dan nilai string.

Contoh:

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

Saya bingung karena sintaks Javascript. Di Javascript, tentunya kita bisa melakukan seperti ini:

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

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

tapi nanti saat mengonversi objek tersebut ke string JSON:

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

0

Saya telah memecahkan masalah ini dengan mencetak JSON, lalu memeriksa sumber halaman (CTRL / CMD + U):

print_r(file_get_contents($url));

Ternyata ada <pre>tag tertinggal .


0

Anda harus memastikan poin-poin ini

1. string json Anda tidak memiliki karakter yang tidak diketahui

2. string json dapat dilihat dari penampil json online (Anda dapat mencari di google sebagai penampil online atau pengurai untuk json) seharusnya ditampilkan tanpa kesalahan

3. string Anda tidak memiliki entitas html itu harus teks / string biasa

untuk penjelasan poin 3

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

ke (menghapus fungsi htmlentities ())

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

0

Bagi saya, saya harus mematikan error_reporting , agar json_decode () berfungsi dengan benar. Kedengarannya aneh, tapi benar dalam kasus saya. Karena ada beberapa pemberitahuan yang dicetak di antara string JSON yang saya coba pecahkan kodenya.


0

Hal terpenting untuk diingat, ketika Anda mendapatkan hasil NULL dari data JSON yang valid adalah dengan menggunakan perintah berikut:

json_last_error_msg();

Yaitu.

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

Anda kemudian memperbaikinya dengan:

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

0

Jadi, html_entity_decode () berhasil untuk saya. Silakan coba ini.

$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>";
?>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.