Подтвердить что ты не робот

PHP. Extension. Вызовите существующую функцию PHP

Итак, я решил написать расширение для php. Все кажется прекрасным, за исключением того, что я застрял в крошечной проблеме.

У меня есть исходные коды php-5.4.9. Существует файл ext/standard/mail.c с удивительной функцией

PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC)

В моем расширении в acme.c у меня есть

...
#include "php.h"
#include "ext/standard/php_mail.h"
#include "php_ini.h"
...

Итак, php_mail чувствует себя хорошо и отлично работает. Но, очевидно, я хочу использовать код из mail.c, начиная с строки 101 и заканчивая 189 (http://pastie.org/5444192 5-93 соответствующих строк в пасте). Поэтому я поймал себя на идее (в какой-то момент это неудобно), почему бы не назвать PHP_FUNCTION(mail)? К моменту, когда я не мог найти эти макросы, и на самом деле я хотел бы знать, как лучше всего реализовать эту идею.

Мой внутренний инженер zend (новичок) рекомендует использовать call_user_function

ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC);

Но я не могу понять, как это назвать.

Вопрос! Как (пример с функцией mail очень) для вызова функций, определенных PHP_FUNCTION?

4b9b3361

Ответ 1

Самый простой способ выяснить, как работает функция, - найти его на lxr.php.net. Первый пример, который появляется в readline: http://lxr.php.net/xref/PHP_TRUNK/ext/readline/readline.c#474

Использование для mail аналогично. Учитывая аргументы как zvals (to_zval, from_zval, msg_zval), вызов очень прост:

zval *params = { to_zval, from_zval, msg_zval };
zend_uint param_count = 3;
zval *retval_ptr;

zval function_name;
INIT_ZVAL(function_name);
ZVAL_STRING(&function_name, "mail", 1);

if (call_user_function(
        CG(function_table), NULL /* no object */, &function_name,
        retval_ptr, param_count, params TSRMLS_CC
    ) == SUCCESS
) {
    /* do something with retval_ptr here if you like */
}

/* don't forget to free the zvals */
zval_ptr_dtor(&retval_ptr);
zval_dtor(&function_name);

Если у вас уже нет параметров как zvals, вы можете создать их с помощью MAKE_STD_ZVAL и ZVAL_STRING.