Json_encode analysis in PHP _ PHP Tutorial

Source: Internet
Author: User
Json_encode analysis of PHP. 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 json_encode must be used to generate the advantage of json,

I like to use sprintf to spell json format when outputting json,

Two days ago, I was told that it was not standard. 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, is the above standard json format?

{A: 'ABC '}

{'A': 'ABC '}

{A: "abc "}

{"A": "abc "}

We all know that only the fourth type is the standard json format.

I am doing this

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

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

It must also comply with standards.

In this case, I have to answer the question. what is the difference in the json format generated by json_encode?

Code on

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

}

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

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); // output NULL

Break;

Case IS_BOOL:

If (Z_BVAL_P (val )){

Smart_str_appendl (buf, "true", 4); // outputs true

} Else {

Smart_str_appendl (buf, "false", 5); // outputs false

}

Break;

Case IS_LONG:

Smart_str_append_long (buf, Z_LVAL_P (val); // output the value of the long integer.

Break;

Case IS_DOUBLE:

{

Char * d = NULL;

Int len;

Double dbl = Z_DVAL_P (val );

If (! Zend_isinf (dbl )&&! Zend_isnan (dbl) {// non-endless

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_ARRAY: // 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 first. it's very long. comments are directly written in the code.

// 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, signature, JSON_NUMERIC_CHECK, signature, expires, JSON_FORCE_OBJECT, and signature. although 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 are returned directly ""

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

Return;

}

If (options & PHP_JSON_NUMERIC_CHECK) {// check whether the number is 0-9. if it is a number, the data is directly returned as long or 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); // the input value is converted to the corresponding Dec code once, for example, 1 is 49 and a is 97, save it 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, '"'); // input \"

// The following code escapes 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 );

} Else {

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 '<':

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: // until here, the value will be appended to the buf without special characters

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, which is also very simple,

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: json_determine_array_type (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 tag

If (r = PHP_JSON_OUTPUT_ARRAY ){

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;

Zend_hash_internal_pointer_reset_ex (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_data_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] = '\ 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 &~ PHP_JSON_NUMERIC_CHECK TSRMLS_CC );

Smart_str_appendc (buf ,':');

Php_json_encode (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 ,'}');

}

}

After a simple analysis, it is proved that the sprintf method is the same as that used above, and all of them are concatenated strings,

Parser. I like to use sprintf to splice the json format when outputting json. I was told by a friend two days ago that it was not standard and that json_encode must be used to generate the standard...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.