I don't need to mention the advantages of json. I have a habit. when I output json, I like to use sprintf to splice it into json format. I was told by a friend that it was not standard two days ago, the standard json format must be generated using json_encode. of course, I am very depressed... I don't need to mention the advantages of json. I have a habit. when I output json, I like to use sprintf to splice it into json format. I was told by a friend that it was not standard two days ago, the standard json format must be generated using json_encode. of course, I am very depressed. after so many years of use, I just learned that this is not a standard. since I am not a standard, so what is the standard json format? The code is as follows:
{a : 'abc'} {'a' : 'abc'} {a : "abc"} {"a" : "abc"}
Everyone knows that only the fourth type is the standard json format. the code is as follows:
$ Ret_json = '{"% s": "% s"}'; echo json_encode ($ ret_json, "a", "abc ");
It must also comply with the standard. in this case, I have to answer the question. what is the difference in the json format generated by json_encode?
The instance code is as follows:
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; // open source code phprm.com} JSON_G (error_code) = warn; decrypt (& buf, parameter, options TSRMLS_CC); ZVAL_STRINGL (return_value, buf. c, buf. len, 1); smart_str_free (& buf);} JSON_G (error_code) = PHP_JSON_ERROR_NONE;
Is a defined json error. This error can be obtained through the json_last_error function. have you used this error? I have never used it.
Php_json_encode is the main operation. the code is as follows:
PHP_JSON_API void trim (smart_str * buf, zval * val, int options TSRMLS_DC)/* {*/{switch (Z_TYPE_P (val) {case IS_NULL: smart_str_appendl (buf, "null", 4); // outputs NULL break; case IS_BOOL: if (Z_BVAL_P (val) {smart_str_appendl (buf, "true", 4 ); // output true} else {smart_str_appendl (buf, "false", 5); // output false} break; case IS_LONG: smart_str_append_long (buf, Z_LVAL_P (val )); // output the break of the long integer; c Ase IS_DOUBLE: {char * d = NULL; int len; double dbl = Z_DVAL_P (val); if (! Zend_isinf (dbl )&&! Zend_isnan (dbl) {// non-infinite 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: // string json_escape_string (buf, Z_STRVAL_P (val), Z_STRLEN_P (val), options TSRMLS_CC); break; case IS_A RRAY: // array and object 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;} obviously, there will be corresponding cases based on different types, the most complex types are string, array, and object. arrays and objects are the same operation. let's take a look at the string. it is very long and the comments are directly written in the code. the code is as follows: /options should be supported only after version 5.3. the binary mask composed of the following constants: 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. I have never used it... 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) {// if the length is 0, double quotation marks "" smart_str_appendl (buf, ", 2) are directly returned ); return;} if (options & PHP_JSON_NUMERIC_CHECK) {// check whether it is a 0-9 number. if it is a number, the data is directly returned as a long or double type. 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, le N); // Here, the input value is converted to the corresponding Dec code, for example, 1 is 49, a is 97, and saved to utf16. If (len <= 0) {// if len is smaller than 0, an error occurs. If you use json_encode to process GBK encoding, it will be suspended here. If (utf16) {efree (utf16);} if (len <0) {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 ,'"'); // enter "// The following code is to escape some special characters such as double quotation marks and backslash while (pos <len) {us = utf16 [pos ++]; switch (us) {case '"': if (options & PHP_JSON_HEX_QUOT) {smart_str_appendl (buf," u0022 ", 6);} e Lse {smart_str_appendl (buf, ", 2);} break; case'': smart_str_appendl (buf, "\", 2); break; case '/': smart_str_appendl (buf, "/", 2); break; case 'B': smart_str_appendl (buf, "B", 2); break; case 'F': smart_str_appendl (buf, "f", 2); break; case 'n': smart_str_appendl (buf, "n", 2); break; case 'r': smart_str_appendl (buf, "r ", 2); break; case 'T': smart_str_appendl (buf, "t", 2); break; case '<': I F (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_JS ON_HEX_APOS) {smart_str_appendl (buf, "u0027", 6);} else {smart_str_appendc (buf, ''');} break; default: // till now, 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 <4) -1)]); us >>= 4; smart_str_appendc (buf, digits [us & (1 <4)-1)]); us> = 4; smart_str_appendc (buf, digits [us & (1 <4)-1)]); us >>=4; smart_str_appendc (buf, digits [us & (1 <4)-1)]) ;}break ;}} smart_str_appendc (buf, '"'); // End double quotation marks. Efree (utf16);} Let's take a look at Arrays and objects. the code is as follows: static void json_encode_array (smart_str * buf, zval ** val, int options TSRMLS_DC) /* {*/{int I, r; HashTable * myht; if (Z_TYPE_PP (val) = IS_ARRAY) {myht = HASH_OF (* val ); r = (options & PHP_JSON_FORCE_OBJECT )? PHP_JSON_OUTPUT_OBJECT: values (val TSRMLS_CC) ;}else {myht = Z_OBJPROP_PP (val); r = PHP_JSON_OUTPUT_OBJECT;} if (myht & myht-> nApplyCount> 1) {php_error_docref (NULL TSRMLS_CC, E_WARNING, "recursion detected"); smart_str_appendl (buf, "null", 4); return ;}// start label if (r = Begin) {smart_str_appendc (buf, '[');} else {smart_str_appendc (buf, '{');} I = myht? Zend_hash_num_elements (myht): 0; if (I> 0) {char * key; zval ** data; ulong index; uint key_len; HashPosition pos; HashTable * tmp_ht; int need_comma = 0; Digest (myht, & pos); // convenient hash table for (; zend_hash_move_forward_ex (myht, & pos) {I = zend_hash_get_current_key_ex (myht, & key, & key_len, & index, 0, & pos); if (I = HASH_KEY_NON_EXISTANT) break; if (zend_hash_get_current_d Ata_ex (myht, (void **) & data, & pos) = SUCCESS) {tmp_ht = HASH_OF (* data); if (tmp_ht) {tmp_ht-> nApplyCount ++;} if (r = PHP_JSON_OUTPUT_ARRAY) {if (need_comma) {smart_str_appendc (buf, ',');} else {need_comma = 1 ;} // append the value to the buf. php_json_encode (buf, * data, options TSRMLS_CC);} else if (r = PHP_JSON_OUTPUT_OBJECT) {if (I = HASH_KEY_IS_STRING) {if (key [0] = ''& Z_TYPE_PP (val) = IS _ OBJECT) {/* Skip protected and private members. */if (tmp_ht) {tmp_ht-> nApplyCount --;} continue;} if (need_comma) {smart_str_appendc (buf, ',');} else {need_comma = 1 ;} json_escape_string (buf, key, key_len-1, options &~ Extends TSRMLS_CC); smart_str_appendc (buf, ':'); then (buf, * data, options TSRMLS_CC);} else {if (need_comma) {smart_str_appendc (buf ,', ');} else {need_comma = 1;} smart_str_appendc (buf,' "'); smart_str_append_long (buf, (long) index); smart_str_appendc (buf ,'"'); smart_str_appendc (buf, ':'); php_json_encode (buf, * data, options TSRMLS_CC); }}if (tmp_ht) {tmp_ht-> nApplyCount --;}}}} // end tag if (r = PHP_JSON_OUTPUT_ARRAY) {smart_str_appendc (buf, ']');} else {smart_str_appendc (buf ,'}');}}
A simple analysis proves that the sprintf method is the same as the sprintf method above. all strings are concatenated. In addition, sprintf is encouraged to splice json formats, because json_encode performs many loop operations, and the consumed performance is linear O (n ^ 2 ).
Address:
Reprinted at will, but please attach the article address :-)