ทำไมฟังก์ชั่น PHP json_encode จึงแปลงสาย UTF-8 เป็นเอนทิตีฐานสิบหก?


148

ฉันมีสคริปต์ PHP ที่เกี่ยวข้องกับภาษาที่หลากหลาย น่าเสียดายที่เมื่อใดก็ตามที่ฉันพยายามที่จะใช้json_encodeเอาต์พุต Unicode ใด ๆ จะถูกแปลงเป็นเอนทิตีเลขฐานสิบหก นี่เป็นพฤติกรรมที่คาดหวังหรือไม่? มีวิธีใดในการแปลงเอาต์พุตเป็นอักขระ UTF-8

นี่คือตัวอย่างของสิ่งที่ฉันเห็น:

INPUT

echo $text;

เอาท์พุท

База данни грешка.

INPUT

json_encode($text);

เอาท์พุท

"\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u0433\u0440\u0435\u0448\u043a\u0430."

คำตอบ:


355

ตั้งแต่ PHP / 5.4.0 "JSON_UNESCAPED_UNICODE"มีตัวเลือกที่เรียกว่า ลองดูสิ:

http://se2.php.net/json_encode

ดังนั้นคุณควรลอง:

json_encode( $text, JSON_UNESCAPED_UNICODE );

3
เอเอชเอ ขอบคุณ! ฉันควรอ่านเอกสารอย่างละเอียดมากขึ้น ขอบคุณ
David Jones

3
JSON_UNESCAPED_UNICODE เปิดตัวใน PHP 5.4.0 และไม่พร้อมใช้งานในเวอร์ชันก่อนหน้า เมื่อใช้งานในเวอร์ชันก่อนหน้าคุณจะได้รับข้อผิดพลาดนี้: "คำเตือน: json_encode () คาดว่าพารามิเตอร์ 2 จะยาวสตริงที่กำหนดใน ... " ดูคำตอบของ CertaiN ด้านล่างสำหรับวิธีแก้ปัญหา 5.3
Octavian Naicu

ใช้ได้กับตัวอักษรภาษาเดนมาร์กÆ, æ, Ø, ø, Å, åขอบคุณ!
ymerdrengene

เยี่ยมมากนี่เป็นคำตอบที่ฉันต้องการ!
randomizer

2
คุณช่วยชีวิตฉันไว้ ขอบคุณ
Jon Zangitu

57

JSON_UNESCAPED_UNICODE พร้อมใช้งานใน PHP เวอร์ชัน 5.4 หรือใหม่กว่า
รหัสต่อไปนี้สำหรับเวอร์ชั่น 5.3

ปรับปรุง

  • html_entity_decodeมีประสิทธิภาพมากกว่าpack+ mb_convert_encodingเล็กน้อย
  • (*SKIP)(*FAIL)ข้ามแบ็กสแลชเองและอักขระที่ระบุโดยJSON_HEX_*แฟล็ก

 

function raw_json_encode($input, $flags = 0) {
    $fails = implode('|', array_filter(array(
        '\\\\',
        $flags & JSON_HEX_TAG ? 'u003[CE]' : '',
        $flags & JSON_HEX_AMP ? 'u0026' : '',
        $flags & JSON_HEX_APOS ? 'u0027' : '',
        $flags & JSON_HEX_QUOT ? 'u0022' : '',
    )));
    $pattern = "/\\\\(?:(?:$fails)(*SKIP)(*FAIL)|u([0-9a-fA-F]{4}))/";
    $callback = function ($m) {
        return html_entity_decode("&#x$m[1];", ENT_QUOTES, 'UTF-8');
    };
    return preg_replace_callback($pattern, $callback, json_encode($input, $flags));
}

1
ไม่ควร \ u เป็น \ U เช่นตัวพิมพ์ใหญ่หรือไม่
malhal

4
ทางออกที่ดีสำหรับ PHP <5.4;)
qdev

ฉันกำลังค้นหา 3 วันเพื่อค้นหาโซลูชันนี้สำหรับเวอร์ชัน 5.3 เนื่องจากโฮสต์ของฉันไม่ได้อัปเกรดเป็น 5.4 สำหรับฉันคุณเป็นผู้ช่วยชีวิตและเพื่อความสมบูรณ์ฉันต้องการทำเครื่องหมายว่าเป็นคำตอบที่ยอมรับ!
Laci

\\ แก้ไขข้อผิดพลาดเมื่อมีสตริง บทความที่ใหม่กว่าคว้ารุ่นลำดับความสำคัญสูงกว่า\\ \u
mpyw

ควรเพิ่มสิ่งนี้ในไลบรารี php ทำได้ดีมาก
2559

7

คุณต้องการตั้งค่าชุดอักขระและ unescaped unicode

 header('Content-Type: application/json;charset=utf-8');  
 json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);

4

ทางออกหนึ่งคือการเข้ารหัสข้อมูลก่อนแล้วจึงถอดรหัสในไฟล์เดียวกัน:

$string =json_encode($input, JSON_UNESCAPED_UNICODE) ; 
echo $decoded = html_entity_decode( $string );

1

นี่คือโซลูชันรวมของฉันสำหรับ PHP รุ่นต่างๆ

ใน บริษัท ของฉันเรากำลังทำงานกับเซิร์ฟเวอร์ที่แตกต่างกันที่มี PHP เวอร์ชันต่าง ๆ ดังนั้นฉันจึงต้องหาวิธีแก้ปัญหาสำหรับทุกคน

$phpVersion = substr(phpversion(), 0, 3)*1;

if($phpVersion >= 5.4) {
  $encodedValue = json_encode($value, JSON_UNESCAPED_UNICODE);
} else {
  $encodedValue = preg_replace('/\\\\u([a-f0-9]{4})/e', "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($value));
}

เครดิตควรจะไปที่มาร์โก Gasi & abu โซลูชันสำหรับ PHP> = 5.4 มีให้ใน json_encode เอกสาร


0

raw_json_encode () ฟังก์ชั่นด้านบนไม่ได้ช่วยฉันแก้ปัญหา (ด้วยเหตุผลบางอย่างฟังก์ชั่นการโทรกลับเพิ่มข้อผิดพลาดบนเซิร์ฟเวอร์ PHP 5.2.5 ของฉัน)

แต่วิธีอื่นนี้ใช้งานได้จริง

https://www.experts-exchange.com/questions/28628085/json-encode-fails-with-special-characters.html

เครดิตควรจะไปที่มาร์โก Gasi ฉันแค่เรียกฟังก์ชั่นของเขาแทนการเรียก json_encode ():

function jsonRemoveUnicodeSequences( $json_struct )
{ 
    return preg_replace( "/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode( $json_struct ) );
}


-2

ตั้งแต่ที่คุณถาม:

มีวิธีใดในการแปลงเอาต์พุตเป็นอักขระ UTF-8

ทางออกก็คือการใช้utf8_encode

UTF-8นี้จะเข้ารหัสสตริงของคุณเพื่อ

เช่น

foreach ($rows as $key => $row) {
  $rows[$key]["keyword"] = utf8_encode($row["keyword"]);
}

echo json_encode($rows);

2
อย่าใช้สิ่งนี้ ตามที่ระบุไว้ในหน้าเอกสาร PHP, utf8_encode จะเหมาะสมก็ต่อเมื่อสตริงเดิมของคุณคือ ISO-8859-1 (ละติน 1) ที่เข้ารหัส ไม่ใช่จุดประสงค์ทั้งหมด "ตรวจสอบให้แน่ใจว่าฟังก์ชันนี้เป็นสตริงที่เข้ารหัส utf-8"
telomere

-5

นี่เป็นพฤติกรรมที่คาดหวังหรือไม่?

json_encode()ทำงานเฉพาะกับ UTF-8 เข้ารหัสข้อมูล

บางทีคุณอาจได้รับคำตอบให้แปลงได้ที่นี่: cyrillic-characters-in-phps-json-encode

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