php 自定义拓展,php自定义扩展(3)

接着上编来讲php生命周期,

php_request_startup

这个阶段和php_module_startup差不多,都是初始化工作,比php_module_startup简单很多,可以自己看下,重点来看下执行阶段

php_execute_script

用gdb看看调用栈,gdb ./php

在php_execute_script打断点,执行,在看下调用栈,

b php_execute_script

(gdb) r test.php

bt

#0 php_execute_script (primary_file=0x7fffffffe240)

at /www/test/php/php-7.4.3/main/main.c:2541

#1 0x00000000008bbd85 in do_cli (argc=2, argv=0x1425af0)

at /www/test/php/php-7.4.3/sapi/cli/php_cli.c:961

#2 0x00000000008bcd2d in main (argc=2, argv=0x1425af0)

at /www/test/php/php-7.4.3/sapi/cli/php_cli.c:1356

在调用栈可以清楚看到执行流程,现在到/cli/php_cli.c文件看看做了哪些事情,

int c;

zend_file_handle file_handle;

int behavior = PHP_MODE_STANDARD;

char *reflection_what = NULL;

volatile int request_started = 0;

volatile int exit_status = 0;

char *php_optarg = NULL, *orig_optarg = NULL;

int php_optind = 1, orig_optind = 1;

char *exec_direct=NULL, *exec_run=NULL, *exec_begin=NULL, *exec_end=NULL;

char *arg_free=NULL, **arg_excp=&arg_free;

char *script_file=NULL, *translated_path = NULL;

int interactive=0;

int lineno = 0;

const char *param_error=NULL;

int hide_argv = 0;

zend_try {

CG(in_compilation) = 0; /* not initialized but needed for several options */

while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {

switch (c) {

初始化变量,解析命令

到/main/main.c文件看看真正的执行阶段

PHPAPI int php_execute_script(zend_file_handle *primary_file)

{

zend_file_handle *prepend_file_p, *append_file_p;

zend_file_handle prepend_file = {{0}, NULL, NULL, 0, 0}, append_file = {{0}, NULL, NULL, 0, 0};

#if HAVE_BROKEN_GETCWD

volatile int old_cwd_fd = -1;

#else

char *old_cwd;

ALLOCA_FLAG(use_heap)

#endif

int retval = 0;

加载要执行的php文件,通过zend_compile_file进行词法分析 语法分析,生成AST,编译成op_array,也就是指令集,

我们看下指令集,

b zend_execute

c

bt

(gdb) p *op_array

$1 = {type = 2 '\002', arg_flags = "\000\000", fn_flags = 37748736,

function_name = 0x0, scope = 0x0, prototype = 0x0, num_args = 0,

required_num_args = 0, arg_info = 0x0, cache_size = 16, last_var = 2,

T = 4, last = 13, opcodes = 0x7ffff5e8b000, run_time_cache__ptr = 0x0,

static_variables_ptr__ptr = 0x7ffff5e78358, static_variables = 0x0,

vars = 0x7ffff5e790f0, refcount = 0x7ffff5e85000, last_live_range = 0,

last_try_catch = 0, live_range = 0x0, try_catch_array = 0x0,

filename = 0x7ffff5e583c0, line_start = 1, line_end = 12,

doc_comment = 0x0, last_literal = 5, literals = 0x7ffff5e8b1a0,

reserved = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}

然后放到zend虚拟机上执行zend_execute(op_array, retval);这这里可以看到真正执行的是这个zend_execute_ex(execute_data);,它是一个函数指针,我们可以更换它,知道这个,那么我们在写扩展时可以重新写个zend_execute_ex函数替换php默认的,我们自己的就可以做很多事情,像拦截php函数,做性能监控。

请求关闭阶段php_request_shutdown,模块关闭阶段php_module_shutdown这两个阶段主要是做变量销毁,现在我们知道了一个自定义扩展在生命周期里的怎么执行的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值