php中json_encode和json_decode的说明

前言

最近在使用json_encode函数的时候,发现自己以前使用json_encode太简单了。很多细节没有注意到,虽然也能用,但是却引发了一些问题。所以本文主要去记录下json_encode和json_decode的项目用法。

json_encode

函数说明

1
string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )

返回包含所提供值的JSON表示的字符串

详细参数说明

value: 可以是任何非resource类型的任何数据类型的值
options: 对value进行encode的选项,主要是控制特殊字符是否进行unicode编码,可以设置选项如下:

  • JSON_HEX_TAG => 1 : 所有的 <> 符号都被转换成\u003C和\u003E(since 5.3.0)

    1
    2
    3
    $value = "hello <jcak>";
    echo json_encode($value) . "\n"; //输出"hello <jack>"
    echo json_encode($value, JSON_HEX_TAG) . "\n"; //输出"hello \u003Cjack\u003E"
  • JSON_HEX_AMP => 2 : 所有的 & 转换为\u0026(since 5.3.0)

    1
    2
    3
    $value = "hello jack &";
    echo json_encode($value) . "\n"; //输出"hello jack &"
    echo json_encode($value, JSON_HEX_AMP) . "\n"; //输出"hello jack \u0026"
  • JSON_HEX_APOS => 4:所有的单引号 转换成\u0027(since 5.3.0)

    1
    2
    3
    $value = "hello 'jack'";
    echo json_encode($value) . "\n"; //输出"hello 'jack'"
    echo json_encode($value, JSON_HEX_AMP) . "\n"; "hello \u0027jack\u0027"
  • JSON_HEX_QUOT => 8 : 所有的双引号 转换成\u0022(since 5.3.0)

    1
    2
    3
    $value = 'hello "jack"';
    echo json_encode($value) . "\n"; //输出"hello \"jack\"" ,为了区别外层的双引号,增加了转义字符,
    echo json_encode($value, JSON_HEX_QUOT) . "\n"; //输出"hello \u0022jack\u0022"
  • JSON_FORCE_OBJECT => 16 : 当使用非关联数组时,输出一个对象而不是数组。当输出的接收者期待对象并且数组为空时特别有用。(since 5.3.0)

    1
    2
    3
    4
    5
    6
    7
    $value = array("a", "b", "c");
    echo json_encode($value) . "\n"; //输出["a","b","c"]
    echo json_encode($value, JSON_FORCE_OBJECT) . "\n"; //输出{"0":"a","1":"b","2":"c"}
    $value = array();
    echo json_encode($value) . "\n"; //输出[]
    echo json_encode($value, JSON_FORCE_OBJECT) . "\n"; //输出{}
  • JSON_NUMERIC_CHECK => 32 : 将数字字符串编码为数字(since 5.3.3)

    1
    2
    3
    $value = "123456";
    var_dump(json_encode($value)); //输出string(8) ""123456"",可以看出,转换出来的是字符串
    var_dump(json_encode($value, JSON_NUMERIC_CHECK));//输出string(6) "123456",可以看出转换出来的是数字,比不加参数,少两个字符
  • JSON_UNESCAPED_SLASHES => 64 : 不对反斜杠 /进行转义(since 5.4.0)

    1
    2
    3
    $value = "/hello jack";
    echo json_encode($value) . "\n"; //输出 "\/hello jack",做了转义处理
    echo json_encode($value, JSON_UNESCAPED_SLASHES)) . "\n";// 输出string(13) "/hello jack",未作转义处理
  • JSON_PRETTY_PRINT => 128 : 格式化返回的数据,美化输出,一般数组很有效(since 5.4.0)

    1
    2
    3
    4
    5
    6
    7
    $value = array("word" => "hello jack");
    echo json_encode($value) . "\n"; //输出{"word":"hello jack"}
    echo json_encode($value, JSON_PRETTY_PRINT) . "\n";
    //输出如下:
    {
    "word": "hello jack"
    }
  • JSON_UNESCAPED_UNICODE => 256 :从字面上对多字节Unicode字符进行编码,如对中文不进行unicode转码,不会转换为\uXXXX这种格式(since 5.4.0)

    1
    2
    3
    $value = "hello jack, 这是一条测试信息";
    echo json_encode($value) . "\n"; //输出"hello jack, \u8fd9\u662f\u4e00\u6761\u6d4b\u8bd5\u4fe1\u606f"
    echo json_encode($value, JSON_UNESCAPED_UNICODE) . "\n"; //输出"hello jack, 这是一条测试信息"
  • JSON_PARTIAL_OUTPUT_ON_ERROR => 512 :用一些不可修改的值代替失败(since 5.5.0)

  • JSON_PRESERVE_ZERO_FRACTION => 1024 : 确保浮点值始终编码为浮点值(since 5.6.6)
    1
    2
    3
    $value = 277.00000;
    echo json_encode($value) . "\n"; //输出:277,整数
    echo json_encode($value, JSON_PRESERVE_ZERO_FRACTION) . "\n"; //输出277.0 浮点数

depth: 设置最大深度,必须大于0,主要是针对数组来说的,是可以encode的数组的最大深度

1
2
3
4
5
$value = array("name" => "midui", "location" => array("province"=>"beijing", "city"=> "beijing"));
echo json_encode($value) . "\n";
//输出{"name":"midui","location":{"province":"beijing","city":"beijing"}}
echo json_encode($value, JSON_PRESERVE_ZERO_FRACTION, 1) . "\n";
//无法encode,注意,此时把第二个参数修改为JSON_PARTIAL_OUTPUT_ON_ERROR,则可以encode,原因不明

总结

一般来说,我们使用json_encode都没有使用后两个参数,但是在某些特定的情况下,有一些参数还是可以供我们使用的。
如:

  • 需要对特殊符号(<,>,’,”,&)进行编码的,使用JSON_HEX_TAG,JSON_HEX_AMP,JSON_HEX_APOS,JSON_HEX_QUOT
  • 不需要对中文进行编码的情况,使用JSON_UNESCAPED_UNICODE
  • 需要将空数组编码为对象,而不是数组的时候使用JSON_FORCE_OBJECT
  • 如果要使用多个参数,则可以将参数值相加,如同时需要对<和&进行编码,但不对中文编码,那么

    第二个参数值 = JSON_HEX_TAG + JSON_HEX_AMP + JSON_UNESCAPED_UNICODE = 259

    1
    2
    3
    4
    5
    $value = "hello <jack> &, 你是谁";
    echo json_encode($value) . "\n"; //不特殊处理,输出"hello <jack> &, \u4f60\u662f\u8c01"
    echo json_encode($value, 1) . "\n"; //对<,>编码,输出"hello \u003Cjack\u003E &, \u4f60\u662f\u8c01"
    echo json_encode($value, 3) . "\n"; //对<,>,&编码,输出"hello \u003Cjack\u003E \u0026, \u4f60\u662f\u8c01"
    echo json_encode($value, 259) . "\n";//对<,>,&编码,不对中文编码,输出"hello \u003Cjack\u003E \u0026, 你是谁"

json_decode

函数说明

1
mixed json_decode ( string $json [, bool $assoc = FALSE [, int $depth = 512 [, int $options = 0 ]]] )

将一个json字符串转换成php中的数组

详细参数说明

json: 待转换的json串
assoc: TRUE: json串转换为数据;FALSE: 转换为对象
depth: 用户指定的可以处理的递归深度
options: 对json进行decode的选项

  • JSON_BIGINT_AS_STRING: 将大整数转换为字符串而不是浮动,这是默认值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $json = '{"number": 12345678901234567890}';
    $data = json_decode($json);
    var_dump($data);
    //输出
    //object(stdClass)#1 (1) {
    // ["number"]=>
    // float(1.2345678901235E+19)
    //}
    $data2 = json_decode($json, false, 512, JSON_BIGINT_AS_STRING);
    var_dump($data2);
    //object(stdClass)#2 (1) {
    // ["number"]=>
    // string(20) "12345678901234567890"
    //}
  • JSON_OBJECT_AS_ARRAY: 效果不明。。。。详见官网说明

    总结

    改方法的使用方法主要是要记住第二个参数。否则转换成的是对象而不是数据。

json_last_error

函数说明

1
2
int json_last_error ( void )
返回最近一次json_ddecode/json_encode发生的错误

返回结果说明

  • JSON_ERROR_NONE => 0: 未发生错误
  • JSON_ERROR_DEPTH => 1: 超出最大深度
  • JSON_ERROR_STATE_MISMATCH => 2: json格式不正确
  • JSON_ERROR_CTRL_CHAR => 3: 控制字符错误
  • JSON_ERROR_SYNTAX => 4: 语法错误
  • JSON_ERROR_UTF8 => 5: 格式错误的UTF-8字符
  • JSON_ERROR_RECURSION => 6: 要编码的值中的一个或多个递归引用 (since 5.5.0)
  • JSON_ERROR_INF_OR_NAN => 7: 要编码的值中有一个或多个NAN或INF值 (since 5.5.0)
  • JSON_ERROR_UNSUPPORTED_TYPE => 8: 给出了一个无法编码的类型的值 (since 5.5.0)
  • JSON_ERROR_INVALID_PROPERTY_NAME => 9: 给出了一个无法编码的属性名称 (since 7.0.0)
  • JSON_ERROR_UTF16 => 10: 格式错误的UTF-16字符 (since 7.0.0)