Mengapa fungsi PHP json_encode mengubah string UTF-8 menjadi entitas heksadesimal?


148

Saya memiliki skrip PHP yang berhubungan dengan berbagai bahasa. Sayangnya, setiap kali saya mencoba menggunakan json_encode, setiap output Unicode dikonversi ke entitas heksadesimal. Apakah ini perilaku yang diharapkan? Apakah ada cara untuk mengubah output menjadi karakter UTF-8?

Berikut ini contoh dari apa yang saya lihat:

MEMASUKKAN

echo $text;

KELUARAN

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

MEMASUKKAN

json_encode($text);

KELUARAN

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

Jawaban:


355

Sejak PHP / 5.4.0, ada opsi yang disebut "JSON_UNESCAPED_UNICODE". Saksikan berikut ini:

http://se2.php.net/json_encode

Karena itu Anda harus mencoba:

json_encode( $text, JSON_UNESCAPED_UNICODE );

3
Aha. Terima kasih! Seharusnya saya membaca dokumentasinya dengan lebih cermat. Terima kasih.
David Jones

3
JSON_UNESCAPED_UNICODE diperkenalkan di PHP 5.4.0, dan tidak tersedia di versi sebelumnya. Saat menggunakannya di versi sebelumnya, Anda akan mendapatkan kesalahan ini: "Peringatan: json_encode () mengharapkan parameter 2 menjadi panjang, string yang diberikan dalam ...". Lihat jawaban CertaiN di bawah ini untuk solusi 5.3.
Oktavianus Naicu

Ini juga berfungsi dengan huruf-huruf Denmark Æ, æ, Ø, ø, Å, å Terima kasih!
ymerdrengene

Luar biasa, inilah jawaban yang saya cari!
Pengacak

2
Anda baru saja menyelamatkan hidup saya. TERIMA KASIH.
Jon Zangitu

57

JSON_UNESCAPED_UNICODE tersedia di PHP Versi 5.4 atau yang lebih baru.
Kode berikut untuk Versi 5.3.

DIPERBARUI

  • html_entity_decodesedikit lebih efisien daripada pack+ mb_convert_encoding.
  • (*SKIP)(*FAIL)melompati backslash itu sendiri dan karakter yang ditentukan oleh JSON_HEX_*bendera.

 

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
Bukankah seharusnya huruf besar adalah huruf besar?
Malhal

4
Solusi yang bagus untuk PHP <5.4;)
qdev

Saya mencari 3 hari untuk menemukan solusi ini untuk Versi 5.3 karena host saya tidak meningkatkan ke 5.4. Bagi saya, Anda adalah penyelamat hidup dan karena begitu lengkap saya lebih suka menandai ini sebagai jawaban yang diterima!
Laci

Memperbaiki bug saat string berisi \\ . Versi \\ yang lebih baru lebih diprioritaskan daripada \u.
mpyw

Ini harus ditambahkan di perpustakaan php. Kerja bagus.
Beraki

7

Anda suka mengatur charset dan unescaped unicode

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

4

Salah satu solusinya adalah dengan terlebih dahulu menyandikan data dan mendekode dalam file yang sama:

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

1

Ini adalah solusi gabungan saya untuk berbagai versi PHP.

Di perusahaan saya, kami bekerja dengan server yang berbeda dengan berbagai versi PHP, jadi saya harus mencari solusi yang berfungsi untuk semua.

$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));
}

Kredit harus diberikan kepada Marco Gasi & abu . Solusi untuk PHP> = 5.4 disediakan dalam json_encode docs.


0

Fungsi raw_json_encode () di atas tidak menyelesaikan masalah saya (karena beberapa alasan, fungsi panggilan balik menimbulkan kesalahan pada server PHP 5.2.5 saya).

Tetapi solusi lain ini benar-benar berhasil.

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

Kredit harus diberikan kepada Marco Gasi . Saya hanya memanggil fungsinya alih-alih memanggil 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

Karena Anda bertanya:

Apakah ada cara untuk mengubah output menjadi karakter UTF-8?

Solusi lain adalah dengan menggunakan utf8_encode .

Ini akan menyandikan string Anda ke UTF-8.

misalnya

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

echo json_encode($rows);

2
Jangan gunakan ini. Seperti yang dinyatakan dalam halaman doc PHP, utf8_encode hanya sesuai jika string asli Anda adalah ISO-8859-1 (Latin1) yang dikodekan. Ini bukan tujuan semua "pastikan string ini utf-8 dikodekan" fungsi.
telomer

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.