[英]How can I overwrite an internal Zend function with a PHP extension?
Hope this isn't too silly a question to ask.希望这不是一个太愚蠢的问题。 I'm fairly new to C and PHP internals but looking to learn more about them.
我对 C 和 PHP 内部结构相当陌生,但希望了解更多关于它们的信息。
I've recently began looking into development of PHP extensions.我最近开始研究 PHP 扩展的开发。 I'm trying to overwrite an internal function to perform some action, before it executes the original function.
在执行原始函数之前,我试图覆盖内部函数以执行某些操作。
I found an example on http://www.phpinternalsbook.com/php7/extensions_design/hooks.html where they overwrite the var_dump() function.我在http://www.phpinternalsbook.com/php7/extensions_design/hooks.html上找到了一个例子,它们覆盖了 var_dump() 函数。 Though I tried to build on this and compile it but can't seem to get it working properly.
虽然我试图在此基础上构建并编译它,但似乎无法使其正常工作。
Here's the code I currently have:这是我目前拥有的代码:
php_hook.c: 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:配置.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: 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);
When I call var_dump(1)
it just returns int(1)
still.当我调用
var_dump(1)
它仍然只返回int(1)
。 I'm on PHP 7.3 currently.我目前使用的是 PHP 7.3。
I haven´t tested it but I think something like this should work:我还没有测试过,但我认为这样的事情应该可行:
...
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);
}
}
Things I changed:我改变的事情:
ZEND_NAMED_FUNCTION
I used PHP_FUNCTION
ZEND_NAMED_FUNCTION
我用PHP_FUNCTION
EG()
I used CG()
CG()
而不是EG()
CG()
PHP_FN(my_overwrite_var_dump)
PHP_FN(my_overwrite_var_dump)
Let me know how it goes!让我知道事情的后续!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.