2015-06-16 2 views
4

Я много огляделся и никогда не получал хорошую книгу или любую онлайн-документацию по zend_extensions [нашел довольно много на PHP-расширениях, но не сильно на zend_extensions]. Я пишу расширение и хотел бы сделать следующее:Понимание API-интерфейсов zend_execute

1. Захват состояния (главным образом аргументов вызова функции) выполняемых в настоящее время функций. [Я нашел структуру, которая содержит некоторые данные о функции и изучает ее, чтобы найти имена параметров функции, но я не могу найти их значения. если zend_execute_data *execd является указателем на структуру.

execd->function_state.function->common.(arg_info+i)->name) дает имя имени переменной ith agrument для текущей функции]. Как получить значение i-го параметра. Я знаю, что мне нужно читать из стека. Как получить ссылку на параметры в стеке? Есть ли хеш-таблица или что-то еще?

2. Во-вторых, Как пропустить текущую выполняющуюся функцию и перейти к следующей функции/инструкции в скрипте php или заменить код текущей функции кодом из более чистой или безопасной версии этой функции? Из функции zend_execute.

Bigger picture: Я пытаюсь получить состояние функции и принять какое-то решение потока выполнения интерпретатора на основе состояния функции. Я пытаюсь сделать все это из zend_execute(), расположенного в моем zend_extension, поэтому у меня есть только API zend_execute() для выполнения вышеуказанных двух задач. Ниже приведен список структур, с которыми я прошел сейчас, и проверен, чтобы иметь возможность находить значения аргументов текущей функции.

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, поэтому я сожалею, если есть какие-то рекомендации, которые я не придерживался. Я старался быть уступчивым на столько фронтов, сколько мог.

+0

Кто-то пожалуйста, помогите? –

+0

'execd-> function_state.function-> common. (Arg_info + i) -> name)' Кажется, что не задает i-й параметр. :('execd-> function_state.function-> common.arg_info-> name)' Дает имя первого аргумента. Вот и все. Я до сих пор не знаю, как получить другие аргументы. –

ответ

1

Я понял это, проверяя исходный код из папки 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