这篇文章,我们来介绍下如何通过PHP
扩展在PHP
脚本将要退出前执行代码。我们可以看一段Swoole
的协程代码:
1 |
|
执行结果如下:
1 | string(1) "3" |
我们发现,在打印4
之后,PHP
脚本算是执行完了,这个时候,PHP
进程也快要退出了。那为什么还会打印出1
和2
呢?
因为PHP
是一门解释性语言,虽然PHP
脚本的代码跑完了,但是PHP
命令解释器还没有跑完,自然可以让PHP
代码继续跑。所以,实际上,这个代码会这样:
1 |
|
在脚本的最后会调用Event::wait()
来等待事件的结束。(而这里的事件就是定时器的事件)
好的,我们现在通过一个小demo
来实现这个功能。
首先,我们需要创建PHP
扩展的基础骨架。通过ext_skel
工具生成:
1 | [root@64fa874bf7d4 ext]# php ext_skel.php --ext register |
然后进入register
目录:
1 | [root@64fa874bf7d4 ext]# cd register/ |
替换config.m4
为如下内容:
1 | PHP_ARG_ENABLE(register, whether to enable register support, |
然后,我们创建和编写测试脚本:
1 | [root@64fa874bf7d4 register]# touch test.php |
1 |
|
这段脚本只定义了一个test
函数,并没有调用。现在我们的任务就是去调用它。
我们开始编写PHP
扩展。在文件register.c
的PHP_RINIT_FUNCTION
里面注册test
函数:
1 |
|
这里,我们首先对php_shutdown_function_entry
结构进行初始化,php_shutdown_function_entry.arguments
的第一个位置填函数的名字。shutdown_function_entry.arg_count
填写1,因为函数名字也算做是arguments
。初始化完php_shutdown_function_entry
之后,我们调用register_user_shutdown_function
函数即可注册test
函数了。这样,就会在php
请求shutdown
阶段调用我们注册的函数了。
然后编译、安装扩展:
1 | [root@64fa874bf7d4 register]# phpize && ./configure && make && make install |
然后把扩展在php.ini
文件里面进行开启:
1 | ; Enable zlib extension module |
然后执行脚本:
1 | [root@64fa874bf7d4 register]# php test.php |
我们发现,成功的调用了test
函数。
这让我想起了我之前面试腾讯的时候,有一道题目,说是如何在每一个PHP
函数调用之前,都执行一段代码。这个问题以后补上。