PHP decoding and encoding json with unicode characters
Judging from everything you've said, it seems like the original Odómetro
string you're dealing with is encoded with ISO 8859-1, not UTF-8.
Here's why I think so:
json_encode
produced parseable output after you ran the input string throughutf8_encode
, which converts from ISO 8859-1 to UTF-8.- You did say that you got "mangled" output when using
print_r
after doingutf8_encode
, but the mangled output you got is actually exactly what would happen by trying to parse UTF-8 text as ISO 8859-1 (ó is\x63\xb3
in UTF-8, but that sequence isó
in ISO 8859-1. - Your
htmlentities
hackaround solution worked.htmlentities
needs to know what the encoding of the input string to work correctly. If you don't specify one, it assumes ISO 8859-1. (html_entity_decode
, confusingly, defaults to UTF-8, so your method had the effect of converting from ISO 8859-1 to UTF-8.) - You said you had the same problem in Python, which would seem to exclude PHP from being the issue.
PHP will use the \uXXXX
escaping, but as you noted, this is valid JSON.
So, it seems like you need to configure your connection to Postgres so that it will give you UTF-8 strings. The PHP manual indicates you'd do this by appending options='--client_encoding=UTF8'
to the connection string. There's also the possibility that the data currently stored in the database is in the wrong encoding. (You could simply use utf8_encode
, but this will only support characters that are part of ISO 8859-1).
Finally, as another answer noted, you do need to make sure that you're declaring the proper charset, with an HTTP header or otherwise (of course, this particular issue might have just been an artifact of the environment where you did your print_r
testing).
I have found following way to fix this issue... I hope this can help you.
json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);