0%

动手编写第一个PHP扩展

入门篇,动手编写第一个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文件

  • php_hello_world.h:
1
2
3
4
$ diff php_hello_world.h.bak php_hello_world.h
61,62d60
< PHP_FUNCTION(hello_world);
<
  • hello_world.c:
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