php实现文件下载代码继续执行php原始的执行函数测试代码打造php自己的链路追踪和性能监控 php评论功能实现代码
2023-01-20
最近看php源码网站模板,为了验证效果网站制作,写了一个php扩展php实现文件下载代码,主要功能是创建php自己的链接跟踪和性能监控
首先从下载源代码
编译安装使用
现在只是一个基本功能,以后会逐步完善
核心功能是重写PHP的执行函数,也就是经常写的
PHP_MINIT_FUNCTION(pid)
{
REGISTER_INI_ENTRIES();
ori_execute_ex = zend_execute_ex;
zend_execute_ex = pid_execute_ex;
ori_execute_internal = zend_execute_internal;
zend_execute_internal = pid_execute_internal;
return SUCCESS;
}
执行过程中发现是要拦截的函数时,会获取函数的参数返回值并记录日志php实现文件下载代码,继续执行PHP原来的执行函数
ZEND_API void pid_execute_core(int internal, zend_execute_data *execute_data, zval *return_value)
{
char *logs_dir = {0};
char *re_func = {0};
char *file_log = "trace.log";
//从php.ini文件读取拦截函数和日志目录
logs_dir = INI_STR("pid.log_path");
re_func = INI_STR("pid.function");
char *name = (char *) malloc(strlen(logs_dir) + strlen(file_log));
sprintf(name, "%s%s", logs_dir, file_log);
FILE *fp;
if((fp = fopen(name, "a+")) == NULL){
printf("file cannot open \n");
}
zend_function *zf = obtain_zend_function(execute_data);
int flag = 0;
char str_1[512] = {0};
char *token;
const char s[2] = ",";
if (zf->common.function_name != NULL){
sprintf(str_1, ZSTR_VAL(zf->common.function_name));
/* 获取第一个子字符串 */
token = strtok(re_func, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
if(strcmp(str_1, token) == 0){
flag = 1;
fputs("\n执行函数的名字:", fp);
fputs( str_1, fp);
break;
}else{
flag = 0;
}
token = strtok(NULL, s);
}
}
int arg_count = 0;
arg_count = ZEND_CALL_NUM_ARGS(execute_data);
smart_str res = {0};
smart_str buf = {0};
if (arg_count) {
zval *p = ZEND_CALL_ARG(execute_data, 1);
if (execute_data->func->type == ZEND_USER_FUNCTION) {
uint32_t first_extra_arg = execute_data->func->op_array.num_args;
if (first_extra_arg && arg_count > first_extra_arg) {
p = ZEND_CALL_VAR_NUM(execute_data, execute_data->func->op_array.last_var + execute_data->func->op_array.T);
}
}
int i;
for (i = 0; i < arg_count; i++) {
php_var_export_ex(p, 2, &buf);
p++;
}
if(flag == 1){
fputs(";执行函数的参数:", fp);
fputs( ZSTR_VAL(buf.s), fp);
//printf("执行函数的参数 %s ......\n", ZSTR_VAL(buf.s));
}
}
if (internal) {
if (ori_execute_internal) {
ori_execute_internal(execute_data, return_value);
} else {
execute_internal(execute_data, return_value);
}
} else {
ori_execute_ex(execute_data);
}
if (return_value) { /* internal */
php_var_export_ex(return_value, 2, &res);
if(flag == 1){
fputs(";执行函数的返回结果:", fp);
fputs( ZSTR_VAL(res.s), fp);
//printf("内部函数返回的结果 %s === \n", ZSTR_VAL(res.s));
}
} else if (execute_data->return_value) { /* user function */
php_var_export_ex(execute_data->return_value, 2, &res);
if(flag == 1){
fputs(";执行函数的返回结果:", fp);
fputs( ZSTR_VAL(res.s), fp);
//printf("自定义函数返回结果 %s ===\n", ZSTR_VAL(res.s));
}
}
fclose(fp);
}
测试代码
执行函数的名字:aa;执行函数的参数:'nihao'111
array (
0 => 1,
1 => 'yy',
2 => 66,
);执行函数的返回结果:8888
执行函数的名字:date;执行函数的参数:'Y-m-d';执行函数的返回结果:'2021-07-17'
执行函数的名字:aa;执行函数的参数:'nihao'111
array (
0 => 1,
1 => 'yy',
2 => 66,
);执行函数的返回结果:8888
执行函数的名字:date;执行函数的参数:'Y-m-d';执行函数的返回结果:'2021-07-17'