微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用PHP扩展覆盖内部Zend函数?

如何解决如何使用PHP扩展覆盖内部Zend函数?

希望这不是一个愚蠢的问题。我对C和PHP内部人员还很陌生,但希望了解更多有关它们的信息。

我最近开始研究PHP扩展的开发。我正在尝试覆盖内部函数以执行一些操作,然后再执行原始函数

我在http://www.phpinternalsbook.com/php7/extensions_design/hooks.html上找到了一个示例,其中它们覆盖了var_dump()函数。尽管我试图在此基础上进行编译,但似乎无法使其正常工作。

这是我当前拥有的代码

PHP_hook.c:

// include the PHP API itself
#include <PHP.h>
// then include the header of your extension
#include "PHP_hook.h"

// register our function to the PHP API 
// so that PHP kNows,which functions are in this module
zend_function_entry hook_PHP_functions[] = {
    ZEND_NAMED_FE(my_overwrite_var_dump,my_overwrite_var_dump,NULL)
    {NULL,NULL,NULL}
};

// some pieces of information about our module
zend_module_entry hook_PHP_module_entry = {
    STANDARD_MODULE_HEADER,PHP_HOOK_EXTNAME,hook_PHP_functions,PHP_HOOK_VERSION,STANDARD_MODULE_PROPERTIES
};

// use a macro to output additional C code,to make ext dynamically loadable
ZEND_GET_MODULE(hook_PHP)

#if PHP_VERSION_ID < 70200
typedef void (*zif_handler)(INTERNAL_FUNCTION_ParaMETERS);
#endif
zif_handler original_handler_var_dump;

ZEND_NAMED_FUNCTION(my_overwrite_var_dump)
{
    PHP_printf("hooked (var_dump))\n");
    // if we want to call the original function
    original_handler_var_dump(INTERNAL_FUNCTION_ParaM_PAsstHRU);
}

PHP_MINIT_FUNCTION(hook_PHP)
{
    zend_function *original;

    original = zend_hash_str_find_ptr(EG(function_table),"var_dump",sizeof("var_dump")-1);

    if (original != NULL) {
        original_handler_var_dump = original->internal_function.handler;
        original->internal_function.handler = my_overwrite_var_dump;
    }
}

config.m4:

PHP_ARG_ENABLE(PHP_hook,Whether to enable the HelloWorldPHP extension,[ --enable-hook-PHP Enable HelloWorldPHP])

if test "$PHP_HOOK" != "no"; then
    PHP_NEW_EXTENSION(PHP_hook,PHP_hook.c,$ext_shared)
fi

PHP_hook.h:

// we define Module constants
#define PHP_HOOK_EXTNAME "PHP_hook"
#define PHP_HOOK_VERSION "0.0.1"

// then we declare the function to be exported
ZEND_NAMED_FUNCTION(my_overwrite_var_dump);

当我致电var_dump(1)时,它只会仍然返回int(1)。我目前在使用PHP 7.3。

解决方法

我还没有测试过,但是我认为这样应该可以工作:

...

PHP_FUNCTION(my_overwrite_var_dump)
{
    php_printf("hooked (var_dump))\n");
    // if we want to call the original function
    original_handler_var_dump(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}


PHP_MINIT_FUNCTION(hook_php)
{
    zend_function *original;

    original = zend_hash_str_find_ptr(CG(function_table),"var_dump",sizeof("var_dump")-1);

    if (original != NULL) {
        original_handler_var_dump = original->internal_function.handler;
        original->internal_function.handler = PHP_FN(my_overwrite_var_dump);
    }
}

我更改的内容:

  • 我使用ZEND_NAMED_FUNCTION而不是PHP_FUNCTION
  • 我使用EG()而不是CG()
  • 最后一件事是,要覆盖处理程序,您必须使用PHP_FN(my_overwrite_var_dump)

让我知道怎么回事!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。