PHP7 扩展开发(一) 最简方法入门

编辑于 2016-08-10

* 移动设备下, 可左滑手指以查看较宽代码

前言

此系列文章将介绍 PHP7 基本的内核原理和扩展开发.

2017年,PHP5.6 被官方结束积极支持,此系列文章将不再完全适用于 PHP5. 此方面资料较少,如有错误,欢迎发邮件指出.

理解此系列文章的前提条件:

熟悉 PHP 和 C 语言

知道基本的数据结构(链表, 哈希表等)

知道基本的操作系统知识(进程, 线程等)

知道 Linux 的基本操作

感谢以下优秀文章:

Laruence blog, 寸谋笔记, hongweipeng.com

环境准备

* 这篇文章指出 Linux / macOS 等系统下的操作方法, Windows 的在:PHP7 扩展开发(一) 在 Windows 下编译

开发 PHP 扩展需要你编译安装 PHP, 并建议开启 -enable-debug 参数 (这将帮你检测内存泄漏问题, 并把 PHP 错误输出到指定文件).

作为尝试, 也可以 不编译安装 PHP, 但是要确保下载的 PHP 代码版本与已安装 PHP 版本一致.

从官网下载 PHP 源码并解压, 我这里以 PHP7.1 为例.得到目录: php-7.1

生成框架

PHP 已经为我们准备了开发框架, 通过自带的 ext_skel 生成它们,并能生成友好代码的注释:

cd php-5.7.1/ext

#帮助我们生成名为 test 的扩展框架目录
./ext_skel --extname=test

cd test
ls
#这里面有:
#config.m4: 这是 Unix 环境下的 Build System 配置文件,后面将会通过它生成配置和安装
#php_test.h: 这个文件是扩展模块的头文件。遵循C语言一贯的作风,这个里面可以放置一些自定义的结构体、全局变量等等
#test.c: 即主程序

#下面配置 config.m4
vim config.m4

所有以 dnl开头的全是注释,所以真正起作用的没几行
其 8-18 行内容大致为

dnl If your extension references something external, use with:
 
dnl PHP_ARG_WITH(say_hello, for say_hello support,
dnl Make sure that the comment is aligned:
dnl [  --with-say_hello             Include say_hello support])
 
dnl Otherwise use enable:
 
dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,
dnl Make sure that the comment is aligned:
dnl [  --enable-say_hello           Enable say_hello support])

根据它的意思, 我们的 test 扩展并没有引用外部组件,所以将“Otherwise use enable”下面三行的dnl 去掉即可

保存退出, 最后在 test 目录下:

#phpize 帮助我们生成 configure 脚本.
phpize

#参数 --with-php-config 是系统已经安装的 PHP 的环境配置文件路径, 
#一般位于 /usr/local/php/bin/php-config.
./configure --with-php-config=/usr/local/php/bin/php-config

#编译
make

这样, test.so就被编译到了 php-7.1/ext/test/modules 文件夹内

configure 脚本有以下常用参数:

--enable-debug 调试模式. 用于检测内存错误

--enable-maintainer-zts 显式的打开线程安全(后面的文章会详解此特征)

--enable-embed PHP 嵌入式开发

测试

编辑 php 配置文件, 将这个扩展加入到 PHP 中去.

#test.so 默认编译进去了 confirm_test_compiled 函数
#运行

php -r "echo confirm_test_compiled('test');"

如果看到 Congratulations!, 恭喜你成功编译了第一个 PHP 扩展~