ホームページ > バックエンド開発 > PHPチュートリアル > PHP json_encode 解析_PHP チュートリアル

PHP json_encode 解析_PHP チュートリアル

WBOY
リリース: 2016-07-14 10:08:54
オリジナル
951 人が閲覧しました

json の利点については説明しません。

私には習慣があり、json を出力するときに sprintf を使用して json 形式に変換するのが好きです。
2 日前に友人が、これは標準ではないので、標準の json 形式を生成するには json_encode を使用する必要があると言いました。もちろん、私はとても落ち込んでいます。
何年も使ってきたので、これが標準ではないことに気づきました。私は標準ではないので、上記は標準のjson形式ですか?
{a : 'abc'}
{'a' : 'abc'}
{a : "abc"}
{"a" : "abc"}
ご存知のとおり、標準の json 形式は 4 番目のタイプのみです。
私はこれをします
$ret_json='{"%s":"%s"}';
echo json_encode($ret_json,"a","abc");
規格も満たしている必要があります。
この場合、さらに深く尋ねる必要があります。json_encode によって生成される json 形式の違いは何ですか?
コードをアップロードする
静的 PHP_FUNCTION(json_encode)
{
zval *パラメータ
smart_str buf = {0};
長いオプション = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", ¶meter, &options) == FAILURE) {
JSON_G(error_code) = PHP_JSON_ERROR_NONE;
php_json_encode(&buf, パラメータ, オプション TSRMLS_CC);
ZVAL_STRINGL(戻り値, buf.c, buf.len, 1);
smart_str_free(&buf);
}
JSON_G(error_code) = PHP_JSON_ERROR_NONE;
は定義された json エラーで、json_last_error 関数を使用して取得できます。とにかく使ったことがないんです。
php_json_encode がメインの操作です
PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */
{
スイッチ(Z_TYPE_P(val))
ケース IS_NULL:
’ ’ s ‐ 1 out 1 out through out through out through ‐ to ‐ ‐ ‐ ‐ ‐     Smart_str_appendl(buf, "null", 4); // NULL を出力します。
休憩
ケース IS_BOOL:
Smart_str_appendl(buf, "true", ;// true を出力します
smart_str_appendl(buf, "false", 5); // false を出力します
休憩
ケース IS_LONG:
" _P(val)); //長整数値を出力します
休憩
ケース IS_DOUBLE:
int 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 は JSON 仕様に準拠していません。0 としてエンコードされています", dbl); 
Smart_str_appendc(buf, '0'); 
}
}
休憩。 
case IS_STRING://文字串
json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options TSRMLS_CC); 
休憩。 
case IS_ARRAY://数组和对象
case IS_OBJECT:
json_encode_array(buf, &val, options TSRMLS_CC); 
休憩。 
デフォルト:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "型はサポートされていないため、null としてエンコードされています"); 
Smart_str_appendl(buf, "null", 4); 
休憩。 
}
戻る; 
}
明らかに、さまざまなタイプに応じて、対応するケースが存在する可能性があります。
最終的なのは、文字列、数値集合、オブジェクトです。この 3 つの種類、数値集合とオブジェクトは同じ操作です。
先見文字列、長さ、注釈は代コードに直接書き込まれます。
//オプションは 5.3 バージョン以降にサポートされており、以下の常量構成による二項制: JSON_HEX_QUOT、JSON_HEX_TAG、JSON_HEX_AMP、JSON_HEX_APOS、JSON_NUMERIC_CHECK、JSON_PRETTY_PRINT、JSON_UNESCAPED_SLASHES、 ECT、JSON_UNESCAPED_UNICODE。虽然我不使用。。。
static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC) /* {{{ */
{
int pos = 0; 
無署名でショートします。 
unsigned short *utf16; 
if (len == 0) {//如果长度範囲0,直接双引号 "" を返します
smart_str_appendl(buf, """", 2); 
戻る; 
}
If (options & PHP_JSON_NUMERIC_CHECK) {//0 から 9 までの数値であるかどうかを確認します。数値の場合、データはlong 型または double 型として直接返されます。
🎝
int 型;
長い p;
if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
to smart_str_append_long(buf、p);
} else if (type == IS_DOUBLE) {
{
int l = spprintf(&tmp, 0, "%.*k", (int) EG(精度)、d); smart_str_appendl(buf、tmp、l);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g は 0 としてエンコードされています",
); smart_str_appendc(buf、 '0');
}
}
utf16 = (unsigned short *)safe_emalloc(len, sizeof(unsigned short), 0);
len = utf8_to_utf16(utf16, s, len); //入力した値は 1 回処理され、1 は 49、a は 97 など、対応する 12 進コードに変換され、utf16 に保存されます。
if (len
if (utf16) {
efree(utf16);
}
if (len
JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
_
php_error_docref(NULL TSRMLS_CC, E_WARNING, "引数の UTF-8 シーケンスが無効です");
Smart_str_appendl(buf, "null", 4);
} else {
Smart_str_appendl(buf, """", 2);
}
}
smart_str_appendc(buf, '"'); //「
」を入力
//次のコードは、二重引用符、バックスラッシュなどの一部の特殊文字をエスケープします。
while (pos < len)
us = utf16[pos++];
スイッチ (私たち)
ケース「」」:
if(options&php_json_hex_quot){ smart_str_appendl(buf、 "\ u0022"、6);
smart_str_appendl(buf、 "\" "、2);
case '\':
Smart_str_appendl(buf, "\\", 2);
休憩;
ケース '/':
️ Smart_str_appendl(buf, "\/", 2);
ケース「b」:
smart_str_appendl(buf, "\b", 2);
ケース 'f':
Smart_str_appendl(buf, "\f", ;
休憩;
ケース「n」:
smart_str_appendl(buf, 2 );
ケース「r」:
smart_str_appendl(buf, 2 );
case 't':
Smart_str_appendl(buf, "\t", 2) ;
case '<':
if (オプション & PHP_JSON_HEX_TAG) {
Smart_str_appendl(buf, "\u003C", 6); 
} else {
Smart_str_appendc(buf, '<'); 
}
休憩。 
case '>':
if (オプション & PHP_JSON_HEX_TAG) {
Smart_str_appendl(buf, "\u003E", 6); 
} else {
Smart_str_appendc(buf, '>'); 
}
休憩。 
ケース '&':
if (オプション & PHP_JSON_HEX_AMP) {
Smart_str_appendl(buf, "\u0026", 6); 
} else {
Smart_str_appendc(buf, '&'); 
}
休憩。 
ケース「」:
if (オプション & PHP_JSON_HEX_APOS) {
Smart_str_appendl(buf, "\u0027", 6); 
} else {
Smart_str_appendc(buf, ''); 
}
休憩。 
デフォルト: //一直到这里、没特殊字符就会把值appendtobuf中
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&lt;&lt; 4)-1)]); 
私たち>>= 4; 
smart_str_appendc(buf、digits [us&((1&lt;&lt; 4)-1)]); 
私たち>>= 4; 
smart_str_appendc(buf、digits [us&((1&lt;&lt; 4)-1)]); 
私たち>>= 4; 
smart_str_appendc(buf、digits [us&((1&lt;&lt; 4)-1)]); 
}
休憩。 
}
}
smart_str_appendc(buf, '"'); // 二重引き号を終了します。
efree(utf16); 
}
再来看看数组和对象,また很简单,
static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */
{
int i, r; 
ハッシュテーブル *myht; 
if (Z_TYPE_PP(val) == IS_ARRAY) {
myht = HASH_OF(*val); 
r = (オプション & 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, "再帰が検出されました"); 
smart_str_appendl(buf, "null", 4); 
戻る; 
}
//开始标签
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 **データ; 
ulong インデックス。 
uint key_len; 
HashPosition pos; 
ハッシュテーブル *tmp_ht; 
int need_comma = 0; 
zend_hash_internal_pointer_reset_ex(myht, &pos); 
//便利哈希表
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)
休憩。 
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; 
}
//将值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) {
/* 保護されたメンバーと非公開メンバーをスキップします。 */
if(tmp_ht){
tmp_ht->nApplyCount--; 
}
続けます。 
}
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_appendc(buf, '"');
Smart_str_appendc(buf, ':'); 
php_json_encode(buf, *data, options TSRMLS_CC); 
}
}
}
}
//終了タグ
if (r == PHP_JSON_OUTPUT_ARRAY) {
smart_str_appendc(buf, ']');
} else {
smart_str_appendc(buf, '}');
}
}
簡単な分析を通じて、問題は実際には上記の sprintf を使用した方法と同じであることが証明されました。つまり、文字列を結合します。
http://www.bkjia.com/PHPjc/477721.html
www.bkjia.com
tru​​e

http://www.bkjia.com/PHPjc/477721.html技術記事 json の利点については話しません。私は json を出力するときに sprintf を使用して json 形式に変換するのが好きです。2 日前、私の友人はそれが標準ではないと言っていました。 json_encode によって標準化されます...
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート