PHP json_decode () คืนค่า NULL ด้วย JSON ที่ถูกต้อง?


105

ฉันมีวัตถุ JSON นี้เก็บไว้ในไฟล์ข้อความธรรมดา:

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

เมื่อฉันพยายามถอดรหัสด้วยjson_decode()มันจะคืนค่า NULL ทำไม? ไฟล์นั้นอ่านได้ (ฉันลองสะท้อนfile_get_contents()แล้วมันก็ใช้ได้)

ฉันได้ทดสอบ JSON กับhttp://jsonlint.com/แล้วและใช้ได้อย่างสมบูรณ์แบบ

เกิดอะไรขึ้นที่นี่?

สารละลาย

มองหาคำตอบใน Google ผมได้กลับไป SO: json_decode ผลตอบแทนโมฆะหลังจากการเรียกเว็บเซอร์ ไฟล์ JSON ของฉันมีลำดับ UTF BOM (อักขระไบนารีบางตัวที่ไม่ควรมี) ดังนั้นจึงทำลายโครงสร้าง JSON ไปที่ Hex Editor ลบไบต์ ทุกอย่างกลับมาเป็นปกติ เหตุใดจึงเกิดขึ้น เนื่องจากฉันแก้ไขไฟล์โดยใช้ Notepad ของ Microsoft Windows ไอเดียแย่มาก!


5
ทำงานกับ PHP 5.2.9; ดังนั้นฉันไม่สามารถใช้json_last_error().
Joel A. Villarreal Bertoldi

1
นอกจากนี้โปรดทราบว่าสิ่งนี้สามารถเกิดขึ้นได้กับอักขระอื่น ๆ ที่ไม่ถูกต้องตรงกลางไฟล์ ฉันเพิ่งมี json_decode () คืนค่า null เนื่องจากสตริงมีหนึ่งในเครื่องหมายขีดกลางพิเศษเหล่านี้ซึ่งอาจถูกวางจาก MS Word และอาจเข้ารหัสผิด ในการระบุอักขระที่เป็นปัญหาให้เปิดไฟล์ JSON (ฉันใช้ใน Notepad ++) เปลี่ยนการเข้ารหัส (โดยไม่ต้องแปลง) และบันทึกเป็นสำเนา จากนั้นแตกไฟล์ทั้งสองไฟล์ (ฉันใช้ WinMerge)
LinusR

(ปัญหา Windows Notepad) โปรดปรึกษาสิ่งนี้ฉันแชร์ปัญหาด้วยและได้รับการแก้ไขแล้ว: stackoverflow.com/questions/10290849/…
Felix Aballi

ที่เป็นไปได้ที่ซ้ำกันของjson_decode จะคืนค่า NULL หลังจากการเรียก
ใช้

สำหรับฉันมันไม่ได้มีอะไรพิเศษเพียงแค่เครื่องหมายจุลภาคพิเศษต่อท้ายองค์ประกอบของวัตถุ นำออกไป: สิ่งใดก็ตามที่ทำให้ JSON ของคุณไม่สอดคล้องกันจะทำให้เกิดข้อผิดพลาด เคล็ดลับโบนัส: อย่าไว้ใจ jsonviewer.stack.hu ใช้บางอย่างเช่น jsonlint
Aman Alam

คำตอบ:


71

อาจเป็นการเข้ารหัสอักขระพิเศษ คุณสามารถขอให้json_last_error ()เพื่อรับข้อมูลที่ชัดเจน

อัปเดต: ปัญหาได้รับการแก้ไขแล้วให้ดูที่ย่อหน้า "โซลูชัน" ในคำถาม


ฉันใช้อักขระพิเศษมาตั้งแต่เริ่มแอปพลิเคชันและไม่มีปัญหามาก่อน ในเครื่องการถอดรหัส JSON ทำงานได้อย่างสมบูรณ์แบบ บนเซิร์ฟเวอร์ของฉันมันไม่ได้ และฉันโทรไม่ได้json_last_error()เพราะเป็น PHP 5.2.9 ฟังก์ชั่นนั้นปรากฏบน PHP 5.3.0
Joel A. Villarreal Bertoldi

1
ไม่น่าจะใช้ได้ ฉันไม่สามารถทำการทดสอบเพิ่มเติมได้ในตอนนี้ถ้าฉันไปได้ในภายหลังฉันจะโพสต์ที่นี่ นอกจากนี้ยังมีคำแนะนำบางประการในบันทึกย่อที่ผู้ใช้มีส่วนร่วม: de.php.net/json_decodeอาจช่วยได้
Pekka

1
สำหรับฉันบน PHP 5.3 มันใช้งานได้ดีเมื่อข้อความถูกเข้ารหัสเป็น UTF-8 แต่ถ้าฉันส่งผ่านข้อความutf8_decode()ก่อนแล้วก็json_decode()ล้มเหลวอย่างเงียบ ๆ
Matthew

1
@Pekka มองหาคำตอบใน Google ผมได้กลับไป SO: stackoverflow.com/questions/689185/json-decode-returns-null-php ไฟล์ JSON ของฉันมีลำดับ UTF BOM (อักขระไบนารีบางตัวที่ไม่ควรมี) ดังนั้นจึงทำลายโครงสร้าง JSON ไปที่ Hex Editor ลบไบต์ ทุกอย่างกลับมาเป็นปกติ เหตุใดจึงเกิดขึ้น เนื่องจากฉันแก้ไขไฟล์โดยใช้ Notepad ของ Micro $ oft Windows ไอเดียแย่มาก!
Joel A. Villarreal Bertoldi

2
สิ่งนี้ควรได้รับการรายงานว่าเป็นจุดบกพร่องของชาว PHP หาก BOM เป็น UTF8 ที่ถูกต้องก็ไม่ควรสำลักโดยไม่มีเสียงใด ๆ
jmucchiello

87

สิ่งนี้ได้ผลสำหรับฉัน

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

2
ฉันได้ใช้สิ่งนี้และได้รับอาร์เรย์ แต่อักขระเฉพาะภาษาของฉัน (ş, ç, ö, .. ) ก็ถูกลบไปด้วย
zkanoca

5
สิ่งนี้ไม่ถูกต้องหากข้อมูล json เข้ารหัส UTF-8 (หรือการเข้ารหัส UTF ใด ๆ ที่ฉันเดา) จะลบข้อมูลที่เข้ารหัส UTF-8 ที่ถูกต้อง มันอาจจะใช้งานได้ตราบเท่าที่ไฟล์มี แต่ภาษาอังกฤษ แต่นั่นก็เป็นข้อสันนิษฐานที่เสี่ยง ฉันจะไม่ใช้สิ่งนี้
DaedalusAlpha

ด้วยวิธีนี้มันใช้งานได้ แต่ถ้าไม่มีมันไม่ถึงแม้ว่าสองสตริงจะเหมือนกันฉันขาดอะไรไปหรือเปล่า?
Rudie Visser

มันได้ผล! แต่ทำไม? สตริงที่ฉันพยายามถอดรหัสไม่มีตัวอักษรพิเศษอยู่ในนั้น
Tobias Gassmann

น่ากลัว ทำงานให้ฉัน :)
Sohil

32

คุณสามารถลองกับมัน

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

ฉันโทรไปโดยบังเอิญstripslashes()สองครั้งซึ่งลบเครื่องหมายทับที่จำเป็นและทำให้สตริง JSON ไม่ถูกต้อง คำตอบนี้ช่วยให้ฉันเห็นข้อผิดพลาด
Philipp

22

หากคุณตรวจสอบคำขอใน chrome คุณจะเห็นว่า JSON เป็นข้อความดังนั้นจึงมีการเพิ่มโค้ดเปล่าลงใน JSON

คุณสามารถล้างได้โดยใช้

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

จากนั้นคุณสามารถใช้:

json_decode($k)

print_r จะแสดงอาร์เรย์


ขอบคุณสำหรับสิ่งนี้ - หวังว่าคุณจะพบภาษาอังกฤษที่หายไป
Dean_Wilson

ผู้ชายที่คุณเป็นตำนานคิดเรื่องนี้มาทั้งวัน
Sboniso Marcus Nzimande

ทำเพื่อฉัน !! การปรับแต่งง่ายๆที่ฉันทำคือการเพิ่มช่องว่างในการแทนที่ฉันกำลังใช้สิ่งนี้และดูเหมือนว่าจะแทนที่พื้นที่ของฉันด้วย ใช้งานได้ดีในขณะนี้ $k=preg_replace('/\s+/', ' ',$k);
Kash

ปัญหาคือสิ่งนี้จะลบทุกช่องว่างทำให้ข้อความภาษาอังกฤษติดกันทั้งหมดใช่หรือไม่?
CodeGuru

14

ฉันมีปัญหาเดียวกันและฉันแก้ไขได้ง่ายๆโดยการแทนที่อักขระเครื่องหมายคำพูดก่อนที่จะถอดรหัส

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

ค่า JSON ของฉันถูกสร้างขึ้นโดยฟังก์ชัน JSON.stringify


ในกรณีนี้อาจมีการใช้ฟังก์ชัน htmlspecialchars และไม่สามารถแยกวิเคราะห์ JSON ได้อีกต่อไป หากต้องการย้อนกลับมีฟังก์ชัน "htmlspecialchars_decode" แทนการแทนที่ด้วยตนเอง & quot;
Davy

12

บางทีตัวละครที่ซ่อนอยู่อาจยุ่งกับ json ของคุณลองสิ่งนี้:

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

หลังจากลองใช้วิธีแก้ปัญหาทั้งหมดข้างต้นในที่สุดก็ใช้ได้ผลสำหรับฉัน ขอบคุณมาก !!
Anis R.


4

แค่คิดว่าฉันจะเพิ่มสิ่งนี้เมื่อฉันพบปัญหานี้ในวันนี้ หากมีการเติมสตริงรอบสตริง JSON ของคุณ json_decode จะคืนค่า NULL

หากคุณกำลังดึง JSON จากแหล่งอื่นที่ไม่ใช่ตัวแปร PHP คุณควร "ตัด" ก่อน:

$jsonData = trim($jsonData);

4

สิ่งนี้ช่วยให้คุณเข้าใจว่าประเภทของข้อผิดพลาดคืออะไร

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

เพียงบันทึกครั้งเดียว ฉันใช้เวลา 3 ชั่วโมงเพื่อพบว่ามันเป็นเพียงปัญหาการเข้ารหัส html ลองทำตามนี้

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 โดยใช้วิธีการ preg_replace ที่ระบุโดย user2254008 ได้แก้ไขให้ฉันเช่นกัน

สิ่งนี้ไม่ จำกัด เฉพาะ Chrome ดูเหมือนว่าจะเป็นปัญหาการแปลงชุดอักขระ (อย่างน้อยก็ในกรณีของฉัน Unicode -> UTF8) สิ่งนี้ได้แก้ไขปัญหาทั้งหมดที่ฉันพบ

ในฐานะโหนดในอนาคต JSON Object i ที่ถอดรหัสมาจากฟังก์ชัน json.dumps ของ Python สิ่งนี้ทำให้เกิดข้อมูลที่ไม่ถูกสุขอนามัยอื่น ๆ เข้ามาแม้ว่าจะจัดการได้อย่างง่ายดายก็ตาม


1

หากคุณได้รับ json จากฐานข้อมูลให้ใส่

mysqli_set_charset($con, "utf8");

หลังจากกำหนดลิงค์การเชื่อมต่อ $ con


ขอบคุณ TomoMiha นี่คือสิ่งที่เหมาะกับปัญหาทั้งหมดของฉันกับ MySQL ที่มีอักขระพิเศษและเมื่อแปลงโดย json_decode ฟิลด์นั้นจะได้รับ = null ....
KLL


1

สำหรับกรณีของฉันมันเป็นเพราะเครื่องหมายคำพูดเดียวในสตริง JSON

รูปแบบ JSON ยอมรับเฉพาะเครื่องหมายคำพูดคู่สำหรับคีย์และค่าสตริง

ตัวอย่าง:

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

ฉันสับสนเพราะไวยากรณ์ Javascript แน่นอนใน Javascript เราสามารถทำได้ดังนี้:

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

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

แต่ในภายหลังเมื่อแปลงวัตถุเหล่านั้นเป็นสตริง JSON:

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


0

คุณควรตรวจสอบจุดเหล่านี้

1.สตริง json ของคุณไม่มีอักขระที่ไม่รู้จัก

2.สตริง json สามารถดูได้จากโปรแกรมดู json ออนไลน์ (คุณสามารถค้นหาใน Google เป็นโปรแกรมดูออนไลน์หรือตัวแยกวิเคราะห์สำหรับ json) ควรดูโดยไม่มีข้อผิดพลาดใด ๆ

3.สตริงของคุณไม่มีเอนทิตี html ควรเป็นข้อความ / สตริงธรรมดา

สำหรับคำอธิบายจุดที่ 3

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

ถึง (ลบฟังก์ชัน htmlentities ())

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

0

สำหรับฉันฉันต้องปิดerror_reportingเพื่อให้ json_decode () ทำงานได้อย่างถูกต้อง ฟังดูแปลก ๆ แต่เป็นเรื่องจริงในกรณีของฉัน เนื่องจากมีการแจ้งเตือนบางอย่างระหว่างสตริง JSON ที่ฉันพยายามถอดรหัส


0

สิ่งที่สำคัญที่สุดที่ต้องจำไว้เมื่อคุณได้ผลลัพธ์ NULL จากข้อมูล JSON ที่ถูกต้องให้ใช้คำสั่งต่อไปนี้:

json_last_error_msg();

ได้แก่ .

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

จากนั้นคุณแก้ไขด้วย:

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

0

ดังนั้น html_entity_decode () ใช้ได้ผลสำหรับฉัน โปรดลองทำตามนี้

$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>";
?>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.