Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 理解zend_执行API_Php_Php Internals - Fatal编程技术网

Php 理解zend_执行API

Php 理解zend_执行API,php,php-internals,Php,Php Internals,我环顾了很多地方,但从来没有找到一本关于zend_扩展的好书或任何在线文档[在PHP扩展上找到了不少,但在zend_扩展上没有太多]。我正在写一个扩展,并想做以下工作: 1。捕获当前执行函数的状态(主要是函数调用的参数)。[我找到了一个包含一些函数数据的结构,并在其中查找函数参数名称,但找不到它们的值。ifzend\u execute\u data*execd是结构指针 execd->function\u state.function->common.(arg\u info+i)->name)给

我环顾了很多地方,但从来没有找到一本关于zend_扩展的好书或任何在线文档[在PHP扩展上找到了不少,但在zend_扩展上没有太多]。我正在写一个扩展,并想做以下工作:

1。捕获当前执行函数的状态(主要是函数调用的参数)。[我找到了一个包含一些函数数据的结构,并在其中查找函数参数名称,但找不到它们的值。if
zend\u execute\u data*execd
是结构指针


execd->function\u state.function->common.(arg\u info+i)->name)
给出当前函数的第i个agrument变量名的名称]。如何获取第I个参数的值。我知道我需要从堆栈中读取。如何将引用获取到堆栈中的参数中?有散列表之类的吗

2.其次,如何跳过当前正在执行的函数,跳转到php脚本中的下一个函数/语句,或者用该函数的更干净或安全版本的代码替换当前函数的代码?从zend_执行函数

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;
};
大图:我试图获取函数状态,并根据函数状态对解释器的执行流做出一些决定。我正试图通过位于我的zend_扩展中的
zend_execute()
来完成所有这些,因此我只有
zend_execute()
API来完成上述两项任务。下面是到目前为止我已经检查过的结构列表,这些结构能够找到当前函数的参数值

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仍不清楚


如果您能直接回答我的问题,或者对我今后的工作提出建议,我们将不胜感激。这是我关于堆栈溢出的第一篇文章,如果有任何我没有遵守的准则,我很抱歉。我试图在尽可能多的方面做到兼容。

我通过检查Zend文件夹中的一些源代码发现了这一点。 下面的结构有一个元素,它是一个
void**
,如果它被转换成
(zval**)
,并分配给一个(zval*),然后分配给一个
zval
,则可以访问
zval
的每个元素。原来这是一个很小的问题

typedef struct _zend_function_state {
    zend_function *function;
    void **arguments;
} zend_function_state;
用法示例:

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
给出了名称

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

*(args - (argc - i))

给出值。

有人请帮忙吗?
execd->function\u state.function->common.(arg\u info+i)->name)
似乎也没有给出第i个参数:(
execd->function\u state.function->common.arg\u info->name)
给出第一个参数的名称。就这样。我仍然不确定如何得到其他论点。