AI编程助手
AI免费问答

PHP的json_encode分析

  2016-06-06 19:57   1007浏览 原创

1

2

3

4

{a : 'abc'}

{'a' : 'abc'}

{a : "abc"}

{"a" : "abc"}

1

2

$ret_json='{"%s":"%s"}';

echo json_encode($ret_json,"a","abc");

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

static PHP_FUNCTION(json_encode)

{

        zval *parameter;

        smart_str buf = {0};

        long options = 0;

 

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &parameter, &options) == FAILURE) {

                return;

        }  

 

        JSON_G(error_code) = PHP_JSON_ERROR_NONE;

 

        php_json_encode(&buf, parameter, options TSRMLS_CC);

 

        ZVAL_STRINGL(return_value, buf.c, buf.len, 1);

 

        smart_str_free(&buf);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */

{

        switch (Z_TYPE_P(val))

        {

                case IS_NULL:

                        smart_str_appendl(buf, "null", 4); //输出NULL

                        break;

 

                case IS_BOOL:

                        if (Z_BVAL_P(val)) {

                                smart_str_appendl(buf, "true", 4);//输出true

                        } else {

                                smart_str_appendl(buf, "false", 5);//输出false

                        }

                        break;

 

                case IS_LONG:

                        smart_str_append_long(buf, Z_LVAL_P(val));//输出长整形的值

                        break;

 

                case IS_DOUBLE:

                        {

                                char *d = NULL;

                                int len;

                                double dbl = Z_DVAL_P(val);

 

                                if (!zend_isinf(dbl) && !zend_isnan(dbl)) {//非无穷尽

                                        len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl);

                                        smart_str_appendl(buf, d, len);

                                        efree(d);

                                } else {

                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);

                                        smart_str_appendc(buf, '0');

                                }

                       }

                        break;

 

                case IS_STRING://字符串

                        json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options TSRMLS_CC);

                        break;

 

                case IS_ARRAY://数组和对象

                case IS_OBJECT:

                        json_encode_array(buf, &val, options TSRMLS_CC);

                        break;

 

                default:

                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");

                        smart_str_appendl(buf, "null", 4);

                        break;

        }

 

        return;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

//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.虽然我没用过。。。

static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC) /* {{{ */

{

        int pos = 0;

        unsigned short us;

        unsigned short *utf16;

 

        if (len == 0) {//如果长度为0,则直接返回 双引号 ""

                smart_str_appendl(buf, """", 2);

                return;

        }

 

        if (options & PHP_JSON_NUMERIC_CHECK) {//检测是否为0-9的数字,如果是数字,那么就会直接把数据作为long或double类型返回。

                double d;

                int type;

                long p;

 

                if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {

                        if (type == IS_LONG) {

                                smart_str_append_long(buf, p);

                        } else if (type == IS_DOUBLE) {

                                if (!zend_isinf(d) && !zend_isnan(d)) {

                                        char *tmp;

                                        int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);

                                        smart_str_appendl(buf, tmp, l);

                                        efree(tmp);

                                } else {

                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);

                                        smart_str_appendc(buf, '0');

                                }

                        }

                        return;

                }

 

        }

 

        utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);

        len = utf8_to_utf16(utf16, s, len); //这里会对你输入的值一次处理转成对应的Dec码,比如1是49,a是97这样的,保存到utf16中。

        if (len //如果len小于0 说明出错。如果用json_encode处理GBK的编码,就会在这里挂掉。

                if (utf16) {

                        efree(utf16);

                }

                if (len

                        JSON_G(error_code) = PHP_JSON_ERROR_UTF8;

                        if (!PG(display_errors)) {

                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument");

                        }

                        smart_str_appendl(buf, "null", 4);

                } else {

                        smart_str_appendl(buf, """", 2);

                }

                return;

        }

 

        smart_str_appendc(buf, '"'); //输入 "

 

//下面这一段代码就是将一些特殊字符转义如 双引号,反斜线等等

        while (pos

        {

                us = utf16[pos++];

 

                switch (us)

                {

                        case '"':

                                if (options & PHP_JSON_HEX_QUOT) {

                                        smart_str_appendl(buf, "\u0022", 6);

                                } else {

                                        smart_str_appendl(buf, "\"", 2);

                                }

                                break;

 

                        case '\':

                                smart_str_appendl(buf, "\\", 2);

                                break;

case '/':

                                smart_str_appendl(buf, "\/", 2);

                                break;

 

                        case '':

                                smart_str_appendl(buf, "\b", 2);

                                break;

 

                        case ' ':

                                smart_str_appendl(buf, "\f", 2);

                                break;

 

                        case ' ':

                                smart_str_appendl(buf, "\n", 2);

                                break;

 

                        case ' ':

                                smart_str_appendl(buf, "\r", 2);

                                break;

 

                        case ' ':

                                smart_str_appendl(buf, "\t", 2);

                                break;

 

                        case ':

                                if (options & PHP_JSON_HEX_TAG) {

                                        smart_str_appendl(buf, "\u003C", 6);

                                } else {

                                        smart_str_appendc(buf, ');

                                }

                                break;

 

                        case '>':

                                if (options & PHP_JSON_HEX_TAG) {

                                        smart_str_appendl(buf, "\u003E", 6);

                                } else {

                                        smart_str_appendc(buf, '>');

}

                                break;

 

                        case '&':

                                if (options & PHP_JSON_HEX_AMP) {

                                        smart_str_appendl(buf, "\u0026", 6);

                                } else {

                                        smart_str_appendc(buf, '&');

                                }

                                break;

 

                        case ''':

                                if (options & PHP_JSON_HEX_APOS) {

                                        smart_str_appendl(buf, "\u0027", 6);

                                } else {

                                        smart_str_appendc(buf, ''');

                                }

                                break;

 

                        default: //一直到这里,没有特殊字符就会把值append到buf中

                                if (us >= ' ' && (us & 127) == us) {

                                        smart_str_appendc(buf, (unsigned char) us);

                                } else {

                                        smart_str_appendl(buf, "\u", 2);

                                        us = REVERSE16(us);

 

                                        smart_str_appendc(buf, digits[us & ((1

                                        us >>= 4;

                                        smart_str_appendc(buf, digits[us & ((1

                                        us >>= 4;

                                        smart_str_appendc(buf, digits[us & ((1

                                        us >>= 4;

                                        smart_str_appendc(buf, digits[us & ((1

                                }

                                break;

                }

        }

        smart_str_appendc(buf, '"'); //结束 双引号。

        efree(utf16);

}

php免费学习视频:立即学习
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。