php8制作一个简单的php扩展

一直很好奇PHP的扩展是真么制作的,今天网上找一些资料看看,发现还是很简单的。这里记录一下步骤,不过具体的一些细节还不是很清楚。

扩展的目标 是给 php添加一个函数 wpcode,输出 一个字符串

  1. 使用 ext_skel.php 生成一个框架
  2. 添加一个函数到 *.stub.php
  3. 生成头文件
  4. 添加函数的功能
  5. 编译

使用 ext_skel.php 生成一个框架

./ext_skel.php  --ext wpcode

Copying config scripts... done
Copying sources... done
Copying tests... done

Success. The extension is now ready to be compiled. To do so, use the
following steps:

cd /path/to/php-src/ext/wpcode
phpize
./configure
make

Don't forget to run tests once the compilation is done:
make test

Thank you for using PHP!

这里假设扩展的名字是 wpcode 。只需一行命令就可以完成。 ext_skel.php 文件在 php源代码中的 ext 目录

查看生成的框架

$ pwd
/root/lnmp/php-8.0.11/ext/wpcode
[root@wpcode.cn]$ tree
.
├── config.m4
├── config.w32
├── php_wpcode.h
├── tests
│   ├── 001.phpt
│   ├── 002.phpt
│   └── 003.phpt
├── wpcode_arginfo.h
├── wpcode.c
└── wpcode.stub.php

添加一个函数到 wpcode.stub.php

cat wpcode.stub.php
<?php
/** @generate-function-entries */
function test1(): void {}
function test2(string $str = ""): string {}

function wpcode(): void {}

最后一行是添加的

生成一个头文件

php ../../build/gen_stub.php wpcode.stub.php
Saved wpcode_arginfo.h

经过这个步骤,当前的目录会增加一个 头文件 wpcode_arginfo.h

cat wpcode_arginfo.h

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_test1, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_test2, 0, 0, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, str, IS_STRING, 0, "\"\"")
ZEND_END_ARG_INFO()

#define arginfo_wpcode arginfo_test1


ZEND_FUNCTION(test1);
ZEND_FUNCTION(test2);
ZEND_FUNCTION(wpcode);


static const zend_function_entry ext_functions[] = {
        ZEND_FE(test1, arginfo_test1)
        ZEND_FE(test2, arginfo_test2)
        ZEND_FE(wpcode, arginfo_wpcode)
        ZEND_FE_END
};

添加函数的功能

 git diff wpcode.c
diff --git a/wpcode.c b/wpcode.c
index 4e57ade..54d3d10 100644
--- a/wpcode.c
+++ b/wpcode.c
@@ -41,6 +41,9 @@ PHP_FUNCTION(test2)

        RETURN_STR(retval);
 }
+
+PHP_FUNCTION(wpcode) {  php_printf("wpcode.cn test"); }
+
 /* }}}*/

 /* {{{ PHP_RINIT_FUNCTION */

其实就是增加一行 PHP_FUNCTION(wpcode) { php_printf("wpcode.cn test"); }

编译安装

phpize
./configure
make 
make install 

# 最后会显示安装的位置
Installing shared extensions:     /usr/local/php80/lib/php/extensions/no-debug-non-zts-20200930/

测试一下

把扩展添加到php的配置文件中

php 扩展
php -c /etc/php/php80.ini -r 'wpcode();'
wpcode.cn test