7

给PHP7.4编写扩展

 3 years ago
source link: https://aoppp.com/gei-php7-4bian-xie-kuo-zhan/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

给PHP7.4编写扩展

本文是以 PHP7.4 作为基础,讲解如何从零开始创建一个 PHP 扩展。本文主要讲解创建一个扩展的基本步骤都有哪些。示例中,我们将实现如下功能:

<?php

echo hello();

输出内容:

// $ php74 ./hello.php

$ hello word

在扩展中实现一个 hello 方法,调用 hello 方法后,输出 hello word!

生成扩展骨架

首先我们要有一份 php-src

git clone https://github.com/php/php-src.git 
cd php-src
git checkout PHP-7.4.5
cd php-7.4.10/ext
ls

可以看到有一个 ext_skel.php 文件

bcmath    com_dotnet  date  enchant       ffi       ftp      gmp    imap  ldap      mysqli   odbc     pcntl  pdo_dblib     pdo_oci    pdo_sqlite  posix     reflection  simplexml  soap     spl       sysvmsg  tidy       xmlreader  xsl        zlib
bz2       ctype       dba   exif          fileinfo  gd       hash   intl  libxml    mysqlnd  opcache  pcre   pdo_firebird  pdo_odbc   pgsql       pspell    session     skeleton   sockets  sqlite3   sysvsem  tokenizer  xmlrpc     zend_test
calendar  curl        dom   ext_skel.php  filter    gettext  iconv  json  mbstring  oci8     openssl  pdo    pdo_mysql     pdo_pgsql  phar        readline  shmop       snmp       sodium   standard  sysvshm  xml        xmlwriter  zip

这个已经文件已经跟 php 一起发布了,所以我们自定义起来非常方便

php ext_skel.php --ext hello --author aoppp --std

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/hello
phpize
./configure
make

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

Thank you for using PHP!

ext 目录下便生成 hello 目录

扩展骨架说明

-rw-r--r--   1 longshilin  staff   405 Feb 27 16:07 .gitignore
-rw-r--r--   1 longshilin  staff    11 Feb 27 16:07 CREDITS
-rw-r--r--   1 longshilin  staff  3231 Feb 27 16:07 config.m4
-rw-r--r--   1 longshilin  staff   204 Feb 27 16:07 config.w32
-rw-r--r--   1 longshilin  staff  3355 Feb 27 16:07 hello.c
-rw-r--r--   1 longshilin  staff  1425 Feb 27 16:07 php_hello.h
drwxr-xr-x   5 longshilin  staff   160 Feb 27 16:07 tests
  • config.m4配置文件

扩展的 config.m4 文件告诉 UNIX 构建系统哪些扩展 configure 选项是支持的,你需要哪些扩展库,以及哪些源文件要编译成它的一部分。对所有经常使用的 autoconf 宏,包括 PHP 特定的及 autoconf 内建的。

config.m4 的作用就是配合 phpize 工具生成 configure 文件。configure 文件是用于环境检测的。检测扩展编译运行所需的环境是否满足。现在我们开始修改 config.m4 文件。

-w1487

其中,dnl 是注释符号。

上面的代码说,如果你所编写的扩展如果依赖其它的扩展或者 lib 库,需要去掉 PHP_ARG_WITH 相关代码的注释。否则,去掉 PHP_ARG_ENABLE 相关代码段的注释。我们编写的扩展不需要依赖其他的扩展和 lib 库。因此,我们去掉 PHP_ARG_ENABLE 前面的注释。

上图生成的时候就已经指定是不依赖其他的扩展。

  • php_hello.h 头文件
    类似于C语言的头文件,包含了一些自定义的结构和函数声明,在这个demo中暂时不需要改动

  • hello.c代码文件

真正的逻辑代码都在这个文件中

hello.c 里面都是逻辑代码,所以我们增加代码在这个文件中操作即可

了解扩展入口

整个扩展的入口是 zend_module_entry 这个结构,具体的定义可以在 Zend 目录下的zend_modules.h 文件中看到,一共有十几个属性,快速跳过,我们暂时只需要 hello

zend_module_entry hello_module_entry = {
	STANDARD_MODULE_HEADER,
	"hello",					/* Extension name */
	hello_functions,			/* zend_function_entry */
	NULL,							/* PHP_MINIT - Module initialization */
	NULL,							/* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(hello),			/* PHP_RINIT - Request initialization */
	NULL,							/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(hello),			/* PHP_MINFO - Module info */
	PHP_HELLO_VERSION,		/* Version */
	STANDARD_MODULE_PROPERTIES
};

扩展相关属性说明:

  • STANDARD_MODULE_HEADER 帮我们实现了前面6个属性
  • hello 是扩展名称
  • hello_functions 是扩展包含的全部方法的集合,后面5个宏分别代表5个扩展特定方法
  • PHP_HELLO_VERSION 是扩展的版本号,定义在头文件中,如果需要修改的话直接打开php_hello.h 找到 define PHP_LZPAY_VERSION 进行修改
  • STANDARD_MODULE_PROPERTIES 帮我们实现了剩下的属性

hello_functions[] 方法数组中已经有了2个示例方法hello_test1hello_test2,我们参考它写我们的方法,首先我们写一个测试方法,放到函数 PHP_FUNCTION(hello_test2) 后面:

/*新增函数*/
PHP_FUNCTION(hello)
{
     zend_string *strg;
     strg = strpprintf(0, "hello word");
     RETURN_STR(strg);
}

然后在 hello_functions[] 数组中增加我们新写的函数

-w883

因为我是新安装的一个独立的 php7.4,所以我的操作基本上都是带绝对路径的,如果大家就一个环境直接操作就行

cd hello/
/usr/local/Cellar/php/7.4.0/bin/phpize
./configure  --with-php-config=/usr/local/Cellar/php/7.4.0/bin/php-config
make && make install

----------------------------------------------------------------------------
Build complete.
Don't forget to run 'make test'.

Installing shared extensions:     /usr/local/Cellar/php/7.4.0/pecl/20190902/

安装好了,我们配置一下这个扩展

  • ext-hello.ini
[hello]
extension="/usr/local/Cellar/php/7.4.0/pecl/20190902/hello.so"
hello git:(PHP-7.4.5) $ /usr/local/Cellar/php/7.4.0/bin/php -m | grep hello
# 输出成功说明ok
hello

-w910

本文为作者原创或转载,允许转载,由憧憬在 aoppp.com发布 转载请说明文章出处。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK