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
?
Ответы
Ответ 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
.