如何在PHP 5.3中将JSON保存为未转义的UTF-8?

时间:2014-07-24 11:35:46

标签: php json utf-8

我创建了一个JSON文件:

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

我需要将其保存为UTF-8,我不能在PHP 5.3中使用JSON_UNESCAPED_UNICODE。那我现在该怎么办?

5 个答案:

答案 0 :(得分:15)

如果您无法使用JSON_UNESCAPED_UNICODE,那么您可能会在编码后自行取消JSON:

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

这里是example in PHP5.3

但是,这不是必需的,因为任何JSON解析器都应正确解析转义的Unicode字符并返回原始字符串。

编辑:使用的更好模式可能是/(?<!\\\\)\\\\u(\w{4})/,这可以避免错误地取消"\\u1234"之类的JSON序列。 See an example

答案 1 :(得分:5)

完美实施

  • \\(转义反斜杠本身)兼容
  • JSON_HEX_*标志兼容

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

实施例

<?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":"جمهوری اسلامی ایران"}}
*/

答案 2 :(得分:-1)

您可以使用 mbstring 方法:

试试这样:

fwrite($myfile, mb_convert_encoding(json_encode($json), "UTF-8"));

答案 3 :(得分:-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);

答案 4 :(得分:-2)

标题

<?xml version="1.0"?>
<Main>
  <Mainrow>
    <code>xxxx</code>
    <itemname>AAAAA</itemname>
    <qty>5.000</qty>
  </Mainrow>
</Main>

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