5

I created a JSON file:

$json = array(
    "Sample" =>array(
        "context" => $context,
        "date"    => $date
    )
);

$url= "sample.json";
$myfile = fopen($url, "w") or die("Unable to open file!");
fwrite($myfile, json_encode($json));    
fclose($myfile);

I need to save it as UTF-8 and I can't use JSON_UNESCAPED_UNICODE in PHP 5.3. So what should I do now?

cmbuckley
  • 40,217
  • 9
  • 77
  • 91
Saeed Masoumi
  • 8,746
  • 7
  • 57
  • 76
  • 3
    You might be able to work around that: http://php.net/json_encode#105789 – cmbuckley Jul 24 '14 at 11:48
  • What exactly is the result you get now and what exactly is the problem with that? – deceze Jul 24 '14 at 11:52
  • possible duplicate of [Reference: Why are my “special” Unicode characters encoded weird using json_encode?](http://stackoverflow.com/q/22745662/476) – deceze Jul 24 '14 at 11:52
  • @deceze i need to read this json in my android app and in there i need to show the context but with this format i can't see anything readable – Saeed Masoumi Jul 24 '14 at 11:55
  • 1
    You mean just for debugging purposes...? The correct characters should be decoded from that JSON with any correct JSON parser... – deceze Jul 24 '14 at 12:38

5 Answers5

16

If you can't use JSON_UNESCAPED_UNICODE, you could probably unescape the JSON yourself after it's been encoded:

$json = array(
    'Sample' => array(
        'context' => 'جمهوری اسلامی ایران'
    )
);

$encoded = json_encode($json);
var_dump($encoded); // context: "\u062c\u0645..."

$unescaped = preg_replace_callback('/\\\\u(\w{4})/', function ($matches) {
    return html_entity_decode('&#x' . $matches[1] . ';', ENT_COMPAT, 'UTF-8');
}, $encoded);

var_dump($unescaped); // context is unescaped
file_put_contents('sample.json', $unescaped);

Here's an example in PHP5.3.

However, this shouldn't be necessary, as any JSON parser should correctly parse the escaped Unicode characters and give you back your original string.

EDIT: A better pattern to use might be /(?<!\\\\)\\\\u(\w{4})/, which avoids incorrectly unescaping a JSON sequence like "\\u1234". See an example.

cmbuckley
  • 40,217
  • 9
  • 77
  • 91
5

Perfect Implemention

  • Compatible with \\ (escaped backslashes itself)
  • Compatible with JSON_HEX_* flags

 

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

Example

<?php
$json = array(
    'Sample' => array(
        'specialchars' => '<x>& \' "</x>',
        'backslashes' => '\\u0020',
        'context' => 'جمهوری اسلامی ایران',
    )
);

echo raw_json_encode($json, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);

/* 
{"Sample":{"specialchars":"\u003Cx\u003E\u0026 \u0027 \u0022\u003C\/x\u003E","backslashes":"\\u0020","context":"جمهوری اسلامی ایران"}}
*/
Alexander Malakhov
  • 3,383
  • 2
  • 33
  • 58
mpyw
  • 5,526
  • 4
  • 30
  • 36
-1

You can use the mbstring approach:

Try like this:

fwrite($myfile, mb_convert_encoding(json_encode($json), "UTF-8"));
chipaki
  • 52
  • 1
  • 4
  • 2
    This won't work, as it's not an encoding issue; multibyte characters are escaped as `\uXXXX`. `json_encode('é') == '\u00e9'`. – cmbuckley Jul 24 '14 at 13:10
-1
$options = json_encode($optn);
        $arr = explode("\u", $options);
        foreach($arr as $key => $arr1){
            if($arr1[0] == '0'){
                $ascCode = substr($arr1, 0, 4);
                $newCode = html_entity_decode('&#x' .$ascCode. ';', ENT_COMPAT, 'UTF-8');
                $arr[$key] = str_replace($ascCode, $newCode, $arr[$key]);
            }
        }
        $options = implode('', $arr);
YasirPoongadan
  • 683
  • 6
  • 19
-2

Header

setlocale(LC_CTYPE, array('ru_RU.utf8', 'ru_RU.utf8'));
setlocale(LC_ALL, array('ru_RU.utf8', 'ru_RU.utf8'));

Body

json_encode($post_all, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);