45

How can I save a json-encoded string with international characters to the databse and then parse the decoded string in the browser?

<?php           
    $string = "très agréable";  
    // to the database 
    $j_encoded = json_encode(utf8_encode($string)); 
    // get from Database 
    $j_decoded = json_decode($j_encoded); 
?>    
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <?= $j_decoded ?>
</html> 
7
  • Pretty much the way you show. What doesn't work? Commented Nov 2, 2010 at 11:01
  • 1
    it gives me: très agréable Commented Nov 2, 2010 at 11:05
  • 1
    Try setting the charset for your page to UTF-8... <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> in the <head> block Commented Nov 2, 2010 at 11:08
  • 1
    @Mark, that worked, but only when using $j_encoded = json_encode($string); so without the utf8_encode() Commented Nov 2, 2010 at 11:17
  • 1
    @FFish get rid of the utf8_encode() in your code, I just saw that (Edit: ah, you were quicker) Commented Nov 2, 2010 at 11:17

10 Answers 10

82

json utf8 encode and decode:

json_encode($data, JSON_UNESCAPED_UNICODE)

json_decode($json, false, 512, JSON_UNESCAPED_UNICODE)

This was answer from 2015, as Tom mentioned in commments, this flag may not work anymore. It is still mentioned in all predefined JSON constants but not on this function itself exclusively. Could be php updated the flags during all these years, php manual mentions these flags on json_decode:

Bitmask of JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR. The behaviour of these constants is described on the JSON constants page.

https://www.php.net/manual/en/function.json-decode.php

https://www.php.net/manual/en/json.constants.php#constant.json-unescaped-unicode

force utf8 might be helpfull too: http://pastebin.com/2XKqYU49

Sign up to request clarification or add additional context in comments.

5 Comments

why giving minus? I had enough situations where this is THE only way that worked. Don't tell me all the stuff about encoding of file, database etc. There are situations you don't know your resource's encoding and it comes in random. Some utf8 some any other you can imagine.
Only thing that worked for me, i'm building an API and i need to purely print the response as json with encoded chars
Thanks Lukas, this was exactly what I was looking for. It converts encoding such as \u00e9 into é. I just confirmed its usage in the PHP docs (example 2). I am still curious though, is the depth parameter really useful? If the recursion is stopped at some depth, does it mean the json will not be fully en/decoded according to the bitmask?
See also this answer, use JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES
The php manual says JSON_UNESCAPED_UNICODE is not a valid flag for json_decode.
29

This is an encoding issue. It looks like at some point, the data gets represented as ISO-8859-1.

Every part of your process needs to be UTF-8 encoded.

  • The database connection

  • The database tables

  • Your PHP file (if you are using special characters inside that file as shown in your example above)

  • The content-type headers that you output

2 Comments

I think this is the best answer, I need to check my DB encoding!
You could add the code needed to accomplish all of that.
29
  header('Content-Type: application/json; charset=utf-8');

Comments

13

If your source-file is already utf8 then drop the utf8_* functions. php5 is storing strings as array of byte.

you should add a meta tag for encoding within the html AND you should add an http header which sets the transferencoding to utf-8.

<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

and in php

<?php
header('Content-Type: text/html; charset=utf-8');

Comments

5

Try sending the UTF-8 Charset header:

<?php header ('Content-type: text/html; charset=utf-8'); ?>

And the HTML meta:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Comments

5
  1. utf8_decode $j_decoded = utf8_decode(json_decode($j_encoded)); EDIT or to be more correct $j_encoded = json_encode($j_encoded); $j_decoded = json_decode($j_encoded); no need for en/decoding utf8
  2. <meta charset="utf-8" />

4 Comments

Why would one need utf8_decode() (which converts to ISO-8859-1) in a UTF-8 environment?
ok, I see. I have to utf8_decode() as well.. Is there a difference doing utf8_decode(json_decode($j_encoded)) vs json_decode(utf8_decode($j_encoded))?
yes it is, and to be correct you shouldn't use utf8_encode anyway. but the way you used it is the poit. 1 you encode utf8 then json so to get your input you have to decode json and then utf8
@Pekka if you mess up encoding anyway (see the utf8_encode) you have to correct it. ok, don't mess up the encoding is also a solution and i've edited my answer to reflect that
4

For me both methods

<?php

header('Content-Type: text/html; charset=utf-8');

echo json_encode($YourData, \JSON_UNESCAPED_UNICODE);

Comments

1

Work for me :)

function jsonEncodeArray( $array ){
    array_walk_recursive( $array, function(&$item) { 
       $item = utf8_encode( $item ); 
    });
    return json_encode( $array );
}

2 Comments

Thanks, this pointed the way for me, except it made things worse at first! :) then I realized that was because something had obviously been "over encoded" somewhere deeper in the stack, so - perhaps strangely - changing the utf8_encode to utf8_decode solved it.
utf8_decode() is always the go to. Beyond that, your looking at mb_convert_encoding() or my preferred - iconv extension.
0

if you get "unexpected Character" error you should check if there is a BOM (Byte Order Marker saved into your utf-8 json. You can either remove the first character or save if without BOM.

Comments

0

I had the same problem. It might differ depending on how You put the data to the db, but try what worked for me:

$str = json_encode($data);
$str = addslashes($str);

Do this before saving data to db.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.