31-変数の取得

2180 ワード

31-変数の取得
ユーザーがPHP言語で定義した変数をカーネルで入手できますか?答えはもちろん肯定的ですが、zend_を通過する方法を見てみましょう.hash_find()関数は、現在の役割ドメインの下でユーザーが定義した変数を見つけます.zend_hash_find()関数はカーネルが提供するHashTableを操作するAPIの1つで、接触したことがなければ、このように使うことを覚えておけばいいです.
{
    zval **fooval;

    if (zend_hash_find(
            EG(active_symbol_table), //       ,           ,   &EG(symbol_table)
            "foo",
            sizeof("foo"),
            (void**)&fooval
        ) == SUCCESS
    )
    {
        php_printf("    $foo!");
    }
    else
    {
        php_printf("          $foo.");
    }
}

まずポインタを指すポインタを定義しzend_hash_findデEG(active_symbol_table)の役割ドメインの下でfoo($foo)という名前の変数を探します.正常に見つかった場合、この関数はSUCCESSに戻ります.コードを見終わったら、多くの疑問があるに違いありません.なぜsizeof(「foo」)演算を行うのか、foovalはzval**型なのに、なぜvoid**になったのか.そしてなぜ&fooval演算を行うのか、fooval自体がポインタを指すポインタではないでしょうか.答えるべき質問は確かに多いので、あまり心配しないで、これらの質問を持って下へ行きましょう.
まず、カーネル定義HashTableという構造は、単にPHP言語の変数を格納するものではなく、他の多くの場所でHashTable(これが神器)が適用されていることを説明します.HashTableには多くの要素があり、カーネルではbucketと呼ばれています.しかし、各bucketのサイズは固定されているので、bucketに任意のデータを格納したい場合は、メモリを申請してデータを保存し、bucketにポインタを保存するのが最善です.zval fooを例にとると、カーネルはまずポインタメモリを十分に保存してfooを保存することを申請します.例えば、このメモリのアドレスはp、つまりp=&fooで、bucketにpを保存します.このとき、pは実はzval*タイプであることがわかります.bucketがzval**タイプのポインタを直接保存するのではなく、zval**タイプのポインタを保存する理由については、次の章で詳しく説明します.
だから私たちがHashTableに行って変数を探しているとき、得られた値は実はzvalのポインタです.In order to populate that pointer into a calling function’s local storage, the calling function will naturally dereference the local pointer, resulting in a variable of indeterminate type with two levels of indirection (such as void**). Knowing that your “indeterminate type” in this case is zval*, you can see where the type being passed into zend_hash_find() will look different to the compiler, having three levels of indirection rather than two. This is done on purpose here so a simple typecast is added to the function call to silence compiler warnings.
もしzend_hash_find()関数は、SUCCESS定数を返し、zend_を呼び出しているアドレスに割り当てます.hash_find()関数が伝達するfoovalパラメータ、すなわちfoovalは私たちが探しているデータを指します.見つからない場合は、foovalパラメータを変更せず、FAILURE定数を返します.
シンボルテーブルから変数を探す場合、SUCCESSとFAILUREはこの変数が存在するかどうかを表すだけです.