PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > PHP教程 > 正文

    PHP中json_encode的使用

    作者:admin来源:网络浏览:时间:2020-09-30 00:07:50我要评论
    导读:那上面才是标准的json格式?必然也符合标准。既然如此,那我就要刨根问底,json_encode生成的json格式究竟有什么不同?
    那上面才是标准的json格式?
    {a : 'abc'} {'a' : 'abc'} {a : "abc"} {"a" : "abc"}

    必然也符合标准。

    既然如此,那我就要刨根问底,json_encode生成的json格式究竟有什么不同?
    上代码


     
    复制代码代码如下:
    1. static PHP_FUNCTION(json_encode)
    2. {
    3.         zval *parameter;
    4.         smart_str buf = {0};
    5.         long options = 0;
    6.         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &parameter, &options) == FAILURE) {
    7.                 return;
    8.         }
    9.         JSON_G(error_code) = PHP_JSON_ERROR_NONE;
    10.         php_json_encode(&buf, parameter, options TSRMLS_CC);
    11.        ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
    12.         smart_str_free(&buf);
    13. }
    JSON_G(error_code) = PHP_JSON_ERROR_NONE;
    是定义的json错误,该错误可以通过json_last_error函数获取,你用过吗?反正我没用过。
    php_json_encode是主要的操作
     
    复制代码代码如下:
    1. PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */
    2. {
    3.         switch (Z_TYPE_P(val))
    4.         {
    5.                 case IS_NULL:
    6.                         smart_str_appendl(buf, "null", 4); //输出NULL
    7.                         break;
    8.  
    9.                 case IS_BOOL:
    10.                         if (Z_BVAL_P(val)) {
    11.                                 smart_str_appendl(buf, "true", 4);//输出true
    12.                         } else {
    13.                                 smart_str_appendl(buf, "false", 5);//输出false
    14.                         }
    15.                         break;
    16.  
    17.                 case IS_LONG:
    18.                         smart_str_append_long(buf, Z_LVAL_P(val));//输出长整形的值
    19.                         break;
    20.  
    21.                 case IS_DOUBLE:
    22.                         {
    23.                                 char *= NULL;
    24.                                 int len;
    25.                                 double dbl = Z_DVAL_P(val);
    26.  
    27.                                 if (!zend_isinf(dbl) && !zend_isnan(dbl)) {//非无穷尽
    28.                                         len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl);
    29.                                         smart_str_appendl(buf, d, len);
    30.                                         efree(d);
    31.                                 } else {
    32.                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
    33.                                         smart_str_appendc(buf, '0');
    34.                                 }
    35.                        }
    36.                         break;
    37.  
    38.                 case IS_STRING://字符串
    39.                         json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options TSRMLS_CC);
    40.                         break;
    41.  
    42.                 case IS_ARRAY://数组和对象
    43.                 case IS_OBJECT:
    44.                         json_encode_array(buf, &val, options TSRMLS_CC);
    45.                         break;
    46.  
    47.                 default:
    48.                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
    49.                         smart_str_appendl(buf, "null", 4);
    50.                         break;
    51.         }
    52.  
    53.         return;
    54. }

    很明显,根据不同的类型,会有相应的case。
    最复杂的是 字符串 、数组 、对象这三种类型,数组和对象是同一种操作。
    先看看字符串吧,很长,注释直接写在代码里。
     
    复制代码代码如下:
    1. /options应该是5.3版本之后才支持的,由以下常量组成的二进制掩码: JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_UNESCAPED_UNICODE.虽然我没用过。。。
    2. static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC) /* {{{ */
    3. {
    4.         int pos = 0;
    5.         unsigned short us;
    6.         unsigned short *utf16;
    7.  
    8.         if (len == 0) {//如果长度为0,则直接返回 双引号 ""
    9.                 smart_str_appendl(buf, """", 2);
    10.                 return;
    11.         }
    12.  
    13.         if (options & PHP_JSON_NUMERIC_CHECK) {//检测是否为0-9的数字,如果是数字,那么就会直接把数据作为long或double类型返回。
    14.                 double d;
    15.                 int type;
    16.                 long p;
    17.  
    18.                 if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
    19.                         if (type == IS_LONG) {
    20.                                 smart_str_append_long(buf, p);
    21.                         } else if (type == IS_DOUBLE) {
    22.                                 if (!zend_isinf(d) && !zend_isnan(d)) {
    23.                                         char *tmp;
    24.                                         int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);
    25.                                         smart_str_appendl(buf, tmp, l);
    26.                                         efree(tmp);
    27.                                 } else {
    28.                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
    29.                                         smart_str_appendc(buf, '0');
    30.                                 }
    31.                         }
    32.                         return;
    33.                 }
    34.  
    35.         }
    36.  
    37.         utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);
    38.         len = utf8_to_utf16(utf16, s, len); //这里会对你输入的值一次处理转成对应的Dec码,比如1是49,a是97这样的,保存到utf16中。
    39.         if (len <= 0) {//如果len小于0 说明出错。如果用json_encode处理GBK的编码,就会在这里挂掉。
    40.                 if (utf16) {
    41.                         efree(utf16);
    42.                 }
    43.                 if (len < 0) {
    44.                         JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
    45.                         if (!PG(display_errors)) {
    46.                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument");
    47.                         }
    48.                         smart_str_appendl(buf, "null", 4);
    49.                 } else {
    50.                         smart_str_appendl(buf, """", 2);
    51.                 }
    52.                 return;
    53.         }
    54.  
    55.         smart_str_appendc(buf, '"'); //输入 "
    56.  
    57. //下面这一段代码就是将一些特殊字符转义如 双引号,反斜线等等
    58.         while (pos < len)
    59.         {
    60.                 us = utf16[pos++];
    61.  
    62.                 switch (us)
    63.                 {
    64.                         case '"':
    65.                                 if (options & PHP_JSON_HEX_QUOT) {
    66.                                         smart_str_appendl(buf, "\u0022", 6);
    67.                                 } else {
    68.                                         smart_str_appendl(buf, "\"", 2);
    69.                                 }
    70.                                 break;
    71.  
    72.                         case '\':
    73.                                 smart_str_appendl(buf, "\\", 2);
    74.                                 break;
    75. case '/':
    76.                                 smart_str_appendl(buf, "\/", 2);
    77.                                 break;
    78.  
    79.                         case 'b':
    80.                                 smart_str_appendl(buf, "\b", 2);
    81.                                 break;
    82.  
    83.                         case 'f':
    84.                                 smart_str_appendl(buf, "\f", 2);
    85.                                 break;
    86.  
    87.                         case 'n':
    88.                                 smart_str_appendl(buf, "\n", 2);
    89.                                 break;
    90.  
    91.                         case 'r':
    92.                                 smart_str_appendl(buf, "\r", 2);
    93.                                 break;
    94.  
    95.                         case 't':
    96.                                 smart_str_appendl(buf, "\t", 2);
    97.                                 break;
    98.  
    99.                         case '<':
    100.                                 if (options & PHP_JSON_HEX_TAG) {
    101.                                         smart_str_appendl(buf, "\u003C", 6);
    102.                                 } else {
    103.                                         smart_str_appendc(buf, '<');
    104.                                 }
    105.                                 break;
    106.  
    107.                         case '>':
    108.                                 if (options & PHP_JSON_HEX_TAG) {
    109.                                         smart_str_appendl(buf, "\u003E", 6);
    110.                                 } else {
    111.                                         smart_str_appendc(buf, '>');
    112. }
    113.                                 break;
    114.  
    115.                         case '&':
    116.                                 if (options & PHP_JSON_HEX_AMP) {
    117.                                         smart_str_appendl(buf, "\u0026", 6);
    118.                                 } else {
    119.                                         smart_str_appendc(buf, '&');
    120.                                 }
    121.                                 break;
    122.  
    123.                         case ''':
    124.                                 if (options & PHP_JSON_HEX_APOS) {
    125.                                         smart_str_appendl(buf, "\u0027", 6);
    126.                                 } else {
    127.                                         smart_str_appendc(buf, ''');
    128.                                 }
    129.                                 break;
    130.  
    131.                         default: //一直到这里,没有特殊字符就会把值append到buf中
    132.                                 if (us >= ' ' && (us & 127) == us) {
    133.                                         smart_str_appendc(buf, (unsigned char) us);
    134.                                 } else {
    135.                                         smart_str_appendl(buf, "\u", 2);
    136.                                         us = REVERSE16(us);
    137.  
    138.                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
    139.                                         us >>= 4;
    140.                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
    141.                                         us >>= 4;
    142.                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
    143.                                         us >>= 4;
    144.                                         smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
    145.                                 }
    146.                                 break;
    147.                 }
    148.         }
    149.         smart_str_appendc(buf, '"'); //结束 双引号。
    150.         efree(utf16);
    151. }

    通过简单分析,证明了一个问题,跟我上面用sprintf的方法其实是一样的,都是拼接字符串,

    而且 为了性能,更应该鼓励用sprintf来拼接json格式,

    因为 json_encode会进行很多 循环操作,而且所消耗的性能是线性的 O(n^2)。

    转载请注明(B5教程网)原文链接:https://b5.mxunkeji.com/content-10-450-1.html
    相关热词搜索: json_encode