C语言 PHP静态变量是如何在内部实现的



我希望 xdebug 有一天能够浏览所有静态变量和属性,但根据作者的说法,无法在引擎中获取这些变量和属性的列表。这让我感到惊讶,因为静态似乎就像具有隔离范围的全局变量。

它们真的没有存储在哈希表中,还是表条目不可枚举的问题?

PHP 函数

在内部可以有两种类型:内部函数或用户定义的函数。内部函数是用C编写的,可以做"任何事情"。用户定义的函数由其带有元数据的"操作阵列"表示。oparray 包含 PHP/ZE 字节码形式的函数表达式。oparray 的一个元素包含所有静态变量的表。

因此,为了获得所有静态变量,必须遍历所有用户定义的函数(以及所有类中的类方法)并检查该数组。

对于全局函数,这个未经测试的 C 代码可能会解决问题:

int dump_statics(zend_function *function TSRMLS_DC)
{
    if (function->type == ZEND_USER_FUNCTION) {
        ulong    hashIndex    = 0;
        char*    hashKey      = NULL;
        int      hashKeyType  = 0;
        zend_hash_internal_pointer_reset(function->op_array.static_variables);
        while ((hashKeyType = zend_hash_get_current_key(function->op_array.static_variables, &hashKey, &hashIndex, 0)) {
            if (hashKeyType == HASH_KEY_IS_STRING) {
                php_printf("%sn", hashkey);
            }
            zend_hash_move_forward(function->op_array.static_variables);
        }
    }
    return 0;
}
zend_hash_apply(EG(function_table), (apply_func_t) dump_statics TSRMLS_CC);

对于类方法,必须迭代 EG(class_table),然后迭代类条目的包含funtion_table......这是留给读者的练习。(就像测试上面的代码一样)


更新:

我创建了一个简单的PHP扩展来做到这一点。可从 https://github.com/johannes/php-staticvardumper 获得

最新更新