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!

Joel A. Villarreal Bertoldi
sumber
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.

Pekka
sumber
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 );
Dunith Dhanushka
sumber
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']))
Gabriel Castillo Prada
sumber
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.

pengguna2254008
sumber
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.

Yapp Ka Howe
sumber
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);
Albert Abdonor
sumber
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

Jürgen Math
sumber
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);
Phil LaNasa
sumber
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;
}
?>
Enrico Tempesti
sumber
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);
Samuel Kwame Antwi
sumber
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.

Destreyf
sumber
1

Jika Anda mendapatkan json dari database, letakkan

mysqli_set_charset($con, "utf8");

setelah menentukan tautan koneksi $ con

TomoMiha
sumber
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"}"
Tho
sumber
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 .

Jeffrey Roosendaal
sumber
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);
Hassan Saeed
sumber
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.

shasi kanth
sumber
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);
Hibah
sumber
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);
Suman Deol
sumber
-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>";
?>
pengguna2648057
sumber