2013-06-03 6 views
5

tôi gửi một thân JSON POST để dịch vụ web PHP của tôi trông giống như thế này:PHP Unicode trong JSON

{ 
    "foo": "☺" 
} 

Khi tôi echo ra cơ thể trong PHP, tôi thấy điều này:

{ 
    "foo":"\xe2\x98\xba" 
} 

tôi cũng đã cố gắng gửi \uXXXX tương đương:

{ 
    "foo": "\u263a" 
} 

này có hơn nữa, trong đó các chuỗi JSON liệu nhận d có "foo":"\\u263a", nhưng sau json_decode giá trị được chuyển thành \xe2\x98\xba.

Điều này gây ra sự cố khi tôi sử dụng giá trị trong phản hồi JSON. Tôi nhận được:

json_encode(): Invalid UTF-8 sequence in argument 

Tại đơn giản nhất, đây là những gì xảy ra tại sao tôi cố gắng JSON mã hóa các chuỗi:

> php -r 'echo json_encode("\x98\xba\xe2");' 
PHP Warning: json_encode(): Invalid UTF-8 sequence in argument in Command line code on line 1 

Câu hỏi của tôi là: làm thế nào tôi có thể nhận được tốt nhất khuôn mặt cười này từ một kết thúc ứng dụng của tôi cho người khác?

Tôi đánh giá cao bất kỳ trợ giúp nào bạn có thể cung cấp.

+1

Làm thế nào bạn "[...] echo out the body [...]"? – PleaseStand

+1

'echo" \ xe2 \ x98 \ xba ";' hoạt động; hiển thị smilie unicode chính xác. –

+0

@PleaseStand Tôi đã gửi nó đến error_log với 'error_log (file_get_contents ('php: // input'))'. –

Trả lời

2

Tôi tin rằng đây là hành vi chính xác của json_encode. Nếu bạn sử dụng như sau:

<script> 
    alert(
    <?php 
     $a = "☺"; 
     echo json_encode($a); 
    ?> 
    ); 
</script> 

Sản lượng HTML sẽ alert("\u263a"); và cảnh báo sẽ hiển thị từ "\u263a" là một đại diện chính xác của chuỗi trong JavaScript.

Sử dụng JSON_UNESCAPED_UNICODE không đổi làm tham số thứ hai của json_encode trong PHP cũng là một tùy chọn, nhưng chỉ có sẵn cho PHP 5.4.0 hoặc mới hơn.

Trong trường hợp nào bạn định sử dụng giá trị?


Edit:

php -r 'echo json_encode ("\ x98 \ xba \ xe2");'

PHP Warning: json_encode(): không hợp lệ chuỗi UTF-8 trong lập luận trong mã dòng lệnh trên dòng 1

Vấn đề là bạn sử dụng một chuỗi sai ký tự. Nó phải là

echo json_encode("\xe2\x98\xba"); // this works for me 

thay vì

echo json_encode("\x98\xba\xe2"); 
+0

Tôi nghĩ bạn đang ở một nơi nào đó ở đây. Giá trị cần được trả về dưới dạng JSON và đó là nơi tôi đang gặp sự cố. –

+0

@rossmcf Vì vậy, bạn muốn gửi một chuỗi ký tự với ký tự đó là JSON reponse từ PHP, phải không? Và rắc rối là gì? Nếu phản hồi JSON được JavaScript xử lý, nó sẽ hoạt động chính xác ngay cả khi kết quả là '\ u263a' thay vì' ☺'. – Mifeet

+0

Vấn đề là json_encode sẽ không mã hóa ''\ x98 \ xba \ xe2'', ít nhất là trong phiên bản PHP của tôi. –

1

Tôi nghĩ rằng khi bạn mã hóa bạn phải sử dụng json_encode({ foo": "☺"}, JSON_UNESCAPED_UNICODE)

chức năng cơ bản json_encode chỉ hoạt động cho UTF-8 mã hóa vì vậy trước khi bạn mã hóa kiểm tra mã hóa chuỗi, như thế này.

mb_check_encoding("your string", 'UTF-8') ; 

nếu nó trả về false thì bạn có thể chuyển đổi sang UTF-8 sử dụng

utf8_encode("your string"); 
+0

Cảm ơn Arun. Khi tôi thử đề xuất của bạn, json_encode đã xuất: "\ u0098 \ u00ba \ u00e2", hoàn toàn là ba ký tự khác. –

2

json_decode() chức năng của PHP cư xử cho đúng trường hợp đầu vào của bạn, trả lại chuỗi các UTF-8 byte (E2 98 BA) mà đại diện cho nhân vật .

Tuy nhiên, Apache HTTPD áp dụng việc thoát \x (trong hàm ap_escape_logitem()) trước khi ghi dòng vào nhật ký lỗi (như bạn đã làm cho mục đích thử nghiệm sử dụng error_log()). Như đã lưu ý trong tập tin server/gen_test_char.c, "tất cả [...] ký tự 8 bit với bộ bit cao" đều được thoát.

+0

Aha! Cảm ơn vì điều đó. –