了解zend_execute API

时间:2015-06-16 20:18:28

标签: php php-internals

我已经浏览了很多,并且从未在zend_extensions上找到一本好书或任何在线文档[在PHP扩展上发现了很多但在zend_extensions上没有太多]。我正在撰写扩展程序,并希望执行以下操作:

1。捕获当前正在执行的函数的状态(主要是函数调用的参数)。 [我发现了一个包含一些函数数据的结构,并查看它以查找函数参数名称,但无法找到它们的值。如果zend_execute_data *execd是结构指针。

execd->function_state.function->common.(arg_info+i)->name)给出了当前函数的第i个agrument变量名的名称。如何获取ith参数的。我知道我需要从堆栈中读取。如何获取堆栈参数的引用?是否有哈希表或什么?

2. 其次,如何跳过当前正在执行的函数并跳转到php脚本中的下一个函数/语句,或者用清理器中的代码替换当前函数的代码或该功能的安全版本?来自zend_execute函数。

更大的图片:我正在尝试获取函数状态,并根据函数状态对解释器的执行流程做出一些决定。我试图从我的zend_extension中的zend_execute( )做所有这些,所以我只有zend_execute( ) API来完成上述2个任务。下面是我现在经历的结构列表,并检查了能够找到当前函数的参数值。

struct _zend_execute_data {
    struct _zend_op *opline;
    zend_function_state function_state;
    zend_function *fbc; /* Function Being Called */
    zend_class_entry *called_scope;
    zend_op_array *op_array;
    zval *object;
    union _temp_variable *Ts;
    zval ***CVs;
    HashTable *symbol_table;
    struct _zend_execute_data *prev_execute_data;
    zval *old_error_reporting;
    zend_bool nested;
    zval **original_return_value;
    zend_class_entry *current_scope;
    zend_class_entry *current_called_scope;
    zval *current_this;
    zval *current_object;
};

参考

typedef struct _zend_function_state {
    zend_function *function;
    void **arguments;
} zend_function_state;

引用

typedef union _zend_function {
    zend_uchar type;  /* MUST be the first element of this struct! */

    struct {
        zend_uchar type;  /* never used */
        const char *function_name;
        zend_class_entry *scope;
        zend_uint fn_flags;
        union _zend_function *prototype;
        zend_uint num_args;
        zend_uint required_num_args;
        zend_arg_info *arg_info;
    } common;

    zend_op_array op_array;
    zend_internal_function internal_function;
} zend_function;

内部没有太多文档,我也无法加入内部邮件列表。它说我在等待批准。我已经引用了有关PHP扩展编写和书籍的文章,例如"高级PHP编程"而这些方面以及围绕它们的API仍然模糊不清。

我将非常感谢您提供直接答案或任何有关如何从此处取得进展的建议。这是我关于Stack Overflow的第一篇文章,所以如果有任何我没有遵守的指南,我很抱歉。我试图在尽可能多的方面遵守。

2 个答案:

答案 0 :(得分:1)

我想到了检查Zend文件夹中的一些源代码。 如果将void **转换为(zval **)并将其分配给(zval *)然后分配给zval,则以下结构具有zval的元素typedef struct _zend_function_state { zend_function *function; void **arguments; } zend_function_state; 可以访问{1}}。事实证明这是一个非常微不足道的问题。

ptr = (zval**)execd_init->function_state.arguments;
ptr1 = *(ptr-2);
ptr3 = *(ptr-1);
ptr2.value.str.val // gives the string value if type is string
ptr4.value.str.val // gives the second argument of type string

使用示例:

{{1}}

答案 1 :(得分:0)

(*(curr_func->common.arg_info + i)).name

给出名字。

void **args = ex->function_state.arguments;
int argc = (int) (zend_uintptr_t) *args;

*(args - (argc - i))

赋予价值。