ホームページ  >  記事  >  バックエンド開発  >  PHP ソース コード分析: 変数のストアド プロシージャ分解_PHP チュートリアル

PHP ソース コード分析: 変数のストアド プロシージャ分解_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:26:30666ブラウズ

PHP コードは次のとおりです:

コードをコピーします コードは次のとおりです:
$php_var = 1;
C に対応するコードは次のとおりです:

コードをコピーします コードは次のとおりです:zval* c_var //PHP変数ポインタを定義します
; MAKE_STD_ZVAL(c_var); //PHP 変数を初期化します
ZVAL_LONG(c_var,1);//代入
ZEND_SET_SYMBL( EG(active_symbol_table), " php_var ", c_var);//グローバル変数シンボルテーブルに登録します

1.まず最初の行を見てください: zval* c_var;//zval ポインター c_var を宣言します。 zval の構造は次のとおりです。


コードをコピーします

コードは次のとおりです: struct _zval_struct {
/* 変数情報 */
zvalue_value value; /* 変数の値 */
zend_uint refcount; /* ガベージ コレクション中に使用される参照カウント */
zend_uchar 型; /* 変数の型 */
zend_uchar is_ref; /* 参照変数ですか? */
}; typedef struct _zval_struct zval;


値 zvalue_value の構造は次のとおりです:

コードをコピーします


コードは次のとおりです:

typedef Union _zvalue_value { long lval; /* 長い整形*/ Double dval; /* 倍精度型 */
struct { struct { /* 文字列型の値 */
char *val;
イントレン

HashTable *ht; /* 配列型の値 */
zend_object_value obj; /*オブジェクトタイプの値*/
zvalue_value



2つ。次に 2 行目を見てください: MAKE_STD_ZVAL(new_val);// 変数の初期化 関連するマクロは次のとおりです: // Initialization

コードをコピーします


コードは次のとおりです:

#define MAKE_STD_ZVAL(zv) ALLOC_ZVAL(zv); INIT_PZVAL(zv); #ALLOC_ZVAL(z) を定義します ZEND_FAST_ALLOC(z, zval, ZVAL_CACHE_LIST)
#define ZEND_FAST_ALLOC(p, type, fc_type)
(p) = (type *) emalloc(sizeof(type))

#INIT_PZVAL(z) を定義します
(z)->refcount = 1; (z)->refcount = 1; (z)->is_ref = 0;



拡張後:




コードをコピーします
コードは次のとおりです:


(c_var) = (zval *) emalloc(sizeof(zval)) //メモリを割り当てます

; (c_var)->refcount = 1; //参照カウントの初期化

; (c_var)-> is_ref = 0; //引用するかどうか

その機能はメモリの割り当て、refcount、is_refの初期化であることがわかります
3. 3 行目の ZVAL_LONG(c_var,1) を見てみましょう。関連するマクロは次のとおりです。



コードをコピーします
コードは次のとおりです:

//値を定義する

#define ZVAL_LONG(z, l) {

Z_TYPE_P(z) = IS_LONG; Z_LVAL_P(z) = 1; }

#Z_TYPE_P(zval_p) Z_TYPE(*zval_p) を定義します

#Z_TYPE(zval) (zval).type を定義します #定義 Z_LVAL_P(zval_p) Z_LVAL(*zval_p) #Z_LVAL(zval) (zval).value.lval を定義します

次のように展開されました:

コードをコピーします コードは次のとおりです:

(* c_var).type = IS_LONG; (* c_var).value = 1;

4: 次に、4 行目を見てください: ZEND_SET_SYMBOL(EG(active_symbol_table), “php_var”, c_var); まず、PHP 変数がハッシュテーブルに格納されていることを説明します


コードをコピーします コードは次のとおりです:
struct _zend_executor_globals {
…。
HashTablesymbol_table;//グローバル変数のシンボルテーブル
HashTable *active_symbol_table;//ローカル変数のシンボルテーブル
…..
};


Hashtable のキーは変数の名前、つまり php_var で、値は PHP 変数へのポインタ、つまり c_var ポインタです。関連するマクロは次のとおりです。

コードをコピーします

コードは次のとおりです:

#define ZEND_SET_SYMBOL(symtable, name, var) {
        char *_name = (名前);                          
        ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name)+1, var, 1, 0);    
}
// 主要な实现は次の関数です:
#define ZEND_SET_SYMBOL_WITH_LENGTH(symtable, name, name_length, var, _refcount, _is_ref)
    {
        zval **orig_var;                                          
        if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS
            && PZVAL_IS_REF(*orig_var)) {
            (var)->refcount = (*orig_var)->refcount;                   
            (var)->is_ref = 1;                                 
            if (_refcount) {
                (var)->refcount += _refcount-1;                
            }
            zval_dtor(*orig_var);                              
            **orig_var = *(var);                                   
            FREE_ZVAL(var);                                
        } else {
            (var)->is_ref = _is_ref;                               
            if (_refcount) {
                (var)->refcount = _refcount;                       
            }
            zend_hash_update(symtable, (name), (name_length), &(var), sizeof(zval *), NULL);                                                            
        }
    }

この関数の機能:
1. 全局所シンボル表がすでにこの量が存在し、参照型である場合、

あ。 原来量の参照数refcount,is_ref情報赋给c_var;
b. z 値の値を、元のように mysql 接続リソースに指定して解放します。 c. c_var が指定する量の値を元の量に変換します。 d. c_var の内部ストレージは、前述のように $b=&a;
が適用された場合に値が変化することを示しています。

2. 全局所シンボル表にその量が存在しない場合、またはその量が存在するが参照量ではない場合、その値は直接変更されます。

http://www.bkjia.com/PHPjc/824657.html

tru​​ehttp://www.bkjia.com/PHPjc/824657.html技術記事 PHP代码如下: 复制代码 如下: $php_var = 1; C の代コードは次のとおりです。 zval* c_var; //定义PHP变量指针 MAKE_STD_ZVAL(c_var); //初期化...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。