入门篇,动手编写第一个PHP扩展
环境:
- CentOS Linux release 7.4.1708
- php-7.2.13
源码编译安装PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| # 下载PHP源文件 # 选择一个路径,下载。后续步骤若没有特殊声明,均在当前路径下进行 $ wget http://am1.php.net/distributions/php-7.2.13.tar.bz2 # 解压 $ tar -xvjf php-7.2.13.tar.bz2
# 常规编译安装PHP cd php-7.2.13
# 编译安装,若无报错依次执行 $ ./configure --enable-maintainer-zts --enable-debug --enable-cli --enable-fpm $ make $ make test # 可能需要root权限 $ make install
$ cp php.ini-development /usr/local/lib/php.ini
# 查看PHP $ php --ini Configuration File (php.ini) Path: /usr/local/lib Loaded Configuration File: /usr/local/lib/php.ini Scan for additional .ini files in: (none) Additional .ini files parsed: (none)
$ php -v PHP 7.2.13 (cli) (built: Jan 7 2019 17:14:31) ( ZTS DEBUG ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
|
编写扩展
暴露 hello_world方法,返回字符串 “Hello World”
工具:ext_skel
- PHP源码中提供的生成扩展文件基础结构的工具,ext_skel即extension skeleton,扩展骨架
- 路径 ext/ext_skel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| # 进入扩展路径 $ cd ext
# 生成 hello_world 扩展,hello_world 为扩展名 $ ./ext_skel --extname=hello_world
# 在当前目录下生成扩展文件夹hello_world,看一下文件结构: $ tree hello_world/ hello_world/ ├── config.m4 ├── config.w32 ├── CREDITS ├── EXPERIMENTAL ├── hello_world.c ├── hello_world.php ├── php_hello_world.h └── tests └── 001.phpt
|
修改
只需要修改两个文件: php_hello_world.h hello_world.c
由于代码改动较少,此处不列全部代码,只列出diff文件
1 2 3 4
| $ diff php_hello_world.h.bak php_hello_world.h 61,62d60 < PHP_FUNCTION(hello_world); <
|
1 2 3 4 5 6 7 8 9
| $ diff hello_world.c.bak hello_world.c 149d148 < PHP_FE(hello_world, NULL) 177,181d175 < < PHP_FUNCTION(hello_world) < { < RETURN_STRING("Hello World"); < }
|
编译
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ cd hello_world # 生成configure必要文件 $ phpize
$ ./configure --enable-hello_world $ make # 此时在 modules 目录下已生成 .so 文件
# 将so文件复制到扩展目录 $ make install
# 修改 /usr/local/lib/php.ini 文件,添加扩展声明 extension=hello_world
|
验证
1 2 3 4 5 6 7
| # 查看扩展 $ php -m | grep hello_world hello_world
# 调用函数 $ php -r "var_dump(hello_world());" string(11) "Hello World"
|
Reference & Thanks