json_encode กำลังคืนค่า NULL หรือไม่


119

ด้วยเหตุผลบางประการรายการ "description" จะส่งคืนNULLพร้อมรหัสต่อไปนี้:

<?php
include('db.php');

$result = mysql_query('SELECT * FROM `staff` ORDER BY `id` DESC LIMIT 2') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>

นี่คือสคีมาสำหรับฐานข้อมูลของฉัน:

CREATE TABLE `staff` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` longtext COLLATE utf8_unicode_ci,
  `description` longtext COLLATE utf8_unicode_ci,
  `icon` longtext COLLATE utf8_unicode_ci,
  `date` longtext COLLATE utf8_unicode_ci,
  `company` longtext COLLATE utf8_unicode_ci,
  `companyurl` longtext COLLATE utf8_unicode_ci,
  `appurl` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

นี่คือสิ่งที่สะท้อนออกมาในหน้า:

[{"id":"4","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"},{"id":"3","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"}]

ความคิดใด ๆ ?


มาใส่คีย์อาร์เรย์ในเครื่องหมายคำพูดก่อนอื่น
Joost

คุณช่วยให้ข้อมูลสคีมาของตาราง "พนักงาน" ของคุณได้ไหม มีคอลัมน์ที่เรียกว่าคำอธิบายหรือไม่?
mopoke

ฟิลด์เหล่านี้ทั้งหมดจะสะท้อนออกมาถ้าฉันเพียงแค่ทำ echo จาก$r['description']นอกคำสั่ง for ()?
tarnfeld

หรืออาจเป็นตัวอย่างเนื้อหาจาก $ r ['description'] ก็ช่วยได้ ประเภทข้อมูลคืออะไร?
mopoke

คุณช่วยสร้างภาพหน้าจอของ shema ฐานข้อมูลได้ไหม ;-)
streetparade

คำตอบ:


256

ฉันพนันได้เลยว่าคุณกำลังดึงข้อมูลด้วยการเข้ารหัสที่ไม่ใช่ utf8: ลองใส่mysql_query('SET CHARACTER SET utf8')ก่อนSELECTข้อความค้นหาของคุณ


5
สวัสดีคำตอบนี้ช่วยชีวิตฉันขอบคุณ ฉันมีปัญหาเดียวกันที่นี่ ฉันมีค่าที่มีอักขระที่ไม่ใช่ utf8 เช่น "Validação de Formulários" ฉันรู้ว่าคำถามนี้เก่าไปหน่อย แต่นั่นคือความยอดเยี่ยมของอินเทอร์เน็ต !!
fabio

7
mysql_set_charset ดีกว่าด้วยเหตุผลด้านความปลอดภัยตั้งแต่ PHP 5.2.3 ดูรายละเอียดในphp.net/manual/en/function.mysql-set-charset.php
masakielastic

3
เนื่องจาก UTF8 เป็นภาษากลางบนเว็บ แทนที่จะทำให้ API ยุ่งเหยิงด้วยพารามิเตอร์และค่าใช้จ่ายเพิ่มเติม PHP (อย่างเข้มงวด) จะใช้การเข้ารหัสที่พบบ่อยที่สุดทำให้คุณเป็นภาระในการแปลงหากคุณใช้การเข้ารหัสที่ผิดปกติ (หรือเกือบตายอย่างในกรณีของคุณ)
ntd

1
วิธีที่แนะนำในการทำเช่นนี้ได้เปลี่ยนไปแล้ว ฉันพยายามแก้ไขคำตอบนี้เพื่อรวมลิงก์ แต่ถูกปฏิเสธ วิธีที่ถูกต้องอยู่ในคำตอบของฉันด้านล่าง
bejs

1
@VeeK ไม่เพียงพอที่จะจัดเก็บฟิลด์ของคุณใน UTF-8: คุณต้องกำหนดค่าเซิร์ฟเวอร์ของคุณให้ตอบลูกค้าใน UTF-8 AFAIK stock mysql และ mariadb ใช้ latin1.
ntd

118

หากคุณมีอย่างน้อย PHP 5.5 คุณสามารถใช้json_last_error_msg ()ซึ่งจะส่งคืนสตริงที่อธิบายปัญหา

หากคุณไม่มี 5.5 แต่เปิด / สูงกว่า 5.3 คุณสามารถใช้json_last_error ()เพื่อดูว่าปัญหาคืออะไร

มันจะกลับมาเป็นจำนวนเต็มที่คุณสามารถใช้ในการระบุปัญหาในเอกสารของฟังก์ชั่น ปัจจุบัน (2012.01.19) ตัวระบุคือ:

0 = JSON_ERROR_NONE
1 = JSON_ERROR_DEPTH
2 = JSON_ERROR_STATE_MISMATCH
3 = JSON_ERROR_CTRL_CHAR
4 = JSON_ERROR_SYNTAX
5 = JSON_ERROR_UTF8

สิ่งเหล่านี้สามารถเปลี่ยนแปลงได้ในเวอร์ชันอนาคตดังนั้นควรอ่านคู่มือนี้ดีกว่า

หากคุณต่ำกว่า 5.3 แสดงว่าคุณโชคไม่ดีไม่มีทางถามได้ว่าข้อผิดพลาดคืออะไร


18

anwser ของ ntd ไม่สามารถแก้ปัญหาของฉันได้ สำหรับผู้ที่อยู่ในสถานการณ์เดียวกันนี่คือวิธีที่ฉันจัดการข้อผิดพลาดนี้ในที่สุด: เพียงแค่ utf8_encode ผลลัพธ์ของคุณแต่ละรายการ

while($row = mysql_fetch_assoc($result)){
    $rows[] = array_map('utf8_encode', $row);
}

หวังว่าจะช่วยได้!


ฉันมีปัญหาในการเข้ารหัสด้วย w / การเข้ารหัสแบบผสม วิธีแก้ปัญหาที่ฉันพบ: stackoverflow.com/a/3521396/776345
Paschalis

9

ไม่กี่วันที่ผ่านมาฉันมีปัญหา SAME กับ 1 ตาราง

ลองครั้งแรก:

echo json_encode($rows);
echo json_last_error();  // returns 5 ?

ถ้าบรรทัดสุดท้ายผลตอบแทนที่ 5 ปัญหาอยู่กับข้อมูลของคุณ ฉันรู้ว่าตารางของคุณอยู่ใน UTF-8 แต่ไม่ได้ป้อนข้อมูล ตัวอย่างเช่นอินพุตอยู่ในไฟล์ txt แต่สร้างบนเครื่อง Win ด้วยการเข้ารหัสแบบโง่ ๆ (ในกรณีของฉัน Win-1250 = CP1250) และข้อมูลนี้ถูกป้อนลงใน DB

สารละลาย? ค้นหาข้อมูลใหม่ (excel, หน้าเว็บ), แก้ไขไฟล์ txt ต้นทางผ่าน PSPad (หรืออะไรก็ได้), เปลี่ยนการเข้ารหัสเป็น UTF-8 , ลบแถวทั้งหมดและใส่ข้อมูลจากต้นฉบับ บันทึก ใส่ลงในฐานข้อมูล

นอกจากนี้คุณยังสามารถเปลี่ยนการเข้ารหัสเป็น utf-8 จากนั้นเปลี่ยนแถวทั้งหมดด้วยตนเอง (ให้ cols ที่มีอักขระพิเศษ - desc, ... ) เหมาะสำหรับทาส ...


หรือใช้JSON_PARTIAL_OUTPUT_ON_ERRORตัวเลือกเพื่อดูปัญหา (เช่นฟิลด์ที่มี UTF8 จะเป็นค่าว่าง)
Peter Krauss

6

คุณควรส่งสตริงเข้ารหัส utf8 ใน json_encode คุณสามารถใช้utf8_encodeและarray_map()ทำหน้าที่ดังต่อไปนี้:

<?php
    $encoded_rows = array_map('utf8_encode', $rows);
    echo json_encode($encoded_rows);
?>

4

Ahhh !!! มันดูไม่ถูกต้องเลยมันเจ็บหัว ลองอะไรแบบนี้เพิ่มเติม ...

<?php
include('db.php');

$result = mysql_query('SELECT `id`, `name`, `description`, `icon` FROM `staff` ORDER BY `id` DESC LIMIT 20') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>
  • เมื่อทำซ้ำมากกว่าmysql_num_rowsที่คุณควรใช้ไม่ได้< <=คุณควรแคชค่านี้ด้วย (บันทึกลงในตัวแปร) แทนที่จะนับซ้ำทุกลูป ใครจะรู้ว่ามันกำลังทำอะไรอยู่ภายใต้ประทุน ... (อาจจะมีประสิทธิภาพฉันไม่แน่ใจจริงๆ)
  • คุณไม่จำเป็นต้องคัดลอกแต่ละค่าออกมาอย่างโจ่งแจ้งเช่นนั้น ... คุณแค่ทำให้ตัวเองยากขึ้น หากแบบสอบถามส่งคืนค่ามากกว่าที่คุณระบุไว้ที่นั่นให้แสดงรายการเฉพาะที่คุณต้องการใน SQL ของคุณ
  • mysql_fetch_arrayส่งกลับค่าทั้งสองข้างและkey intคุณไม่ได้ใช้ดัชนีดังนั้นอย่าดึงข้อมูลเลย

หากนี่เป็นปัญหาจริงๆjson_encodeฉันขอแนะนำให้เปลี่ยนเนื้อหาของลูปด้วยสิ่งที่ต้องการ

$rows[] = array_map('htmlentities',$row);

Perhpas มีอักขระพิเศษบางอย่างอยู่ในนั้นซึ่งทำให้สิ่งต่าง ๆ เกิดขึ้น ...


[{"id": "4", "name": "Noter 2", "description": null, "icon": "http: \ / \ / images.apple.com \ / webapps \ / ผลผลิต \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ / dbelement.com \ / "," appurl ":" http: \ / \ / noter2.dbelement.com "}, {" id ":" 3 "," name ":" Noter 2 "," description ": null," icon ":" http: \ / \ / images .apple.com \ / webapps \ / ผลผลิต \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ /dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"
tarnfeld

@tarnfield: นั่นคือสิ่งที่คุณต้องการหรือไม่? โอ้.. คุณมีข้อมูลเพิ่มเติมในนั้น ... ที่นี่ ... ให้ฉันแก้ไขให้คุณ
mpen

ใช่ "คำอธิบาย" ส่งคืนnull
tarnfeld

หากคำอธิบายจะกลับnullก็อาจเป็น nullลองecho $row['description'].'<br/>';วนซ้ำและดูว่ามันพูดว่าอย่างไร
mpen

1
สวัสดีคำตอบนี้ช่วยชีวิตฉันขอบคุณ ฉันมีปัญหาเดียวกันที่นี่ ฉันมีค่าที่มีอักขระที่ไม่ใช่ utf8 เช่น "Validação de Formulários" ฉันรู้ว่าคำถามนี้เก่าไปหน่อย แต่นั่นคือความยอดเยี่ยมของอินเทอร์เน็ต !!
fabio


3

สำหรับใครก็ตามที่ใช้ PDO การแก้ปัญหาจะคล้ายกับคำตอบของ ntdคำตอบของ

จากหน้าสร้างPHP PDO :: __ตามความคิดเห็นของผู้ใช้Kiipa ที่ live dot com :

หากต้องการรับชุดอักขระ UTF-8 คุณสามารถระบุได้ใน DSN

$ link = PDO ใหม่ ("mysql: host = localhost; dbname = DB; charset = UTF8 ");


0

สำหรับฉันปัญหาที่ json_encode จะส่งคืนการเข้ารหัส null ของเอนทิตีเนื่องจากการใช้งาน jsonSerialize ของฉันดึงอ็อบเจ็กต์ทั้งหมดสำหรับเอนทิตีที่เกี่ยวข้อง ฉันแก้ไขปัญหาโดยตรวจสอบให้แน่ใจว่าฉันดึง ID ของเอนทิตีที่เกี่ยวข้อง / เกี่ยวข้องและเรียก -> toArray () เมื่อมีมากกว่าหนึ่งเอนทิตีที่เชื่อมโยงกับวัตถุที่จะทำให้เป็นอนุกรม json หมายเหตุฉันกำลังพูดถึงกรณีที่หนึ่งimplements JsonSerializableในเอนทิตี


-4

ฉันมีปัญหาเดียวกันและวิธีแก้ปัญหาคือใช้ฟังก์ชันของตัวเองแทน json_encode()

echo '["' . implode('","', $row) . '"]';
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.