Поэтому я решил написать расширение для 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
?
Самый простой способ выяснить, как работает функция, – найти его на 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
.