调用现有PHP函数的PHP扩展

19

所以我决定写一个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感觉良好且工作正常。但是,显然,我想使用从第101行开始到第189行结束的mail.c代码(在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定义的函数?


能否解释一下从您的扩展中调用 php_mail() 的用例?听起来您的扩展尝试去做太多的事情,要么应该在 PHP 中编写更多代码,要么应该将其编译为独立的二进制文件。请记住,PHP 扩展应该是通用且可重用的,而不应与特定应用程序绑定。能否再详细解释一下这个扩展的功能? - DaveRandom
1个回答

20

找出函数如何工作的最简单方法是在 lxr.php.net 上搜索它。第一个例子出现在 readline 中:http://lxr.php.net/xref/PHP_TRUNK/ext/readline/readline.c#474

mail 的用法类似。给定 zval 作为参数(to_zvalfrom_zvalmsg_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);

如果您没有zval参数,那么可以使用MAKE_STD_ZVALZVAL_STRING来创建它们。


2
哦,很方便,我之前没有见过lxr.php.net。不过,这是最简单的找到API导航的方法,有点遗憾啊! - John Carter
我能否从独立的二进制文件中调用像PHPAPI或PHP_FUNCTION这样的函数?或者它们必须在PHP扩展中? - Olle Härstedt
@NikiC 这个答案对于 PHP 7+ 仍然正确吗? - Pieter van den Ham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接