如何使用 PHP 扩展覆盖内部 Zend 函数?
Posted
技术标签:
【中文标题】如何使用 PHP 扩展覆盖内部 Zend 函数?【英文标题】:How can I overwrite an internal Zend function with a PHP extension? 【发布时间】:2021-01-06 03:50:23 【问题描述】:希望这不是一个愚蠢的问题。我对 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,
NULL,
NULL,
NULL,
NULL,
NULL,
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。
【问题讨论】:
【参考方案1】:我还没有测试过,但我认为这样的东西应该可以工作:
...
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);
我改变的地方:
我用PHP_FUNCTION
代替ZEND_NAMED_FUNCTION
我用CG()
代替EG()
最后一件事是,为了覆盖处理程序,您必须使用PHP_FN(my_overwrite_var_dump)
告诉我进展如何!
【讨论】:
以上是关于如何使用 PHP 扩展覆盖内部 Zend 函数?的主要内容,如果未能解决你的问题,请参考以下文章