新萄京Web前端

 新萄京Web前端     |      2020-03-14

独立的 PHP 扩展可以独立于 PHP 源码之外进行分发。要创建一个这样的扩展,需要准备好两样东西:

因为个性化推荐系统的开发,是架构组与策略组的跨小团队合作,所以策略方不愿意公开自己的代码,所以就只能采用我们提供系统功能,对方提供策略部分.so文件来实现(策略团队以C/C++作为主要语言)。

  • 配置文件 (config.m4)
  • 你的模块源码

一、ext_skel 脚本

PHP 扩展由几个文件组成,这些文件对所有扩展来说都是通用的。不同扩展之间,这些文件的很多细节是相似的,只是要费力去复制每个文件的内容。幸运的是,有脚本可以做所有的初始化工作,名为 ext_新萄京娱乐app,skel,自 PHP 4.0 起与其一起分发。

不带参数运行 ext_skel 在 PHP 5.6.24(最新正式版本) 中会产生以下输出:

./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
           [--skel=dir] [--full-xml] [--no-help]

 --extname=module   module is the name of your extension
  --proto=file       file contains prototypes of functions to create
  --stubs=file       generate only function stubs in file
  --xml              generate xml documentation to be added to phpdoc-svn
  --skel=dir         path to the skeleton directory
  --full-xml         generate xml documentation for a self-contained extension
                     (not yet implemented)
  --no-help          don't try to be nice and create comments in the code
                     and helper functions to test if the module compiled

通常来说,开发一个新扩展时,仅需关注的参数是 --extname 和 --no-help。除非已经熟悉扩展的结构,不要想去使用 --no-help; 指定此参数会造成 ext_skel 在生成文件里省略很多有用的注释。剩下的 --extname 会将扩展的名称传给 ext_skel。"name" 是一个全为小写字母的标识符,仅包含字母和下划线,在 PHP 发行包的 ext/ 文件夹下是唯一的。*** 官网说了:其它参数不用明白,也不要尝试。 ***

接下来我们来描述一下如果创建这些文件并组合起来。

执行创建edutest1

 ✘ zhangxuefeng@zhangxuefengdeMac-mini  ~/Developer/php-5.6.24/ext  ./ext_skel --extname=edutest1
Creating directory edutest1
Creating basic files: config.m4 config.w32 .gitignore edutest1.c php_edutest1.h CREDITS EXPERIMENTAL tests/001.phpt edutest1.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/edutest1/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-edutest1
5.  $ make
6.  $ ./sapi/cli/php -f ext/edutest1/edutest1.php
7.  $ vi ext/edutest1/edutest1.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/edutest1/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.

准备好系统工具

想要扩展能够在系统上编译并成功运行,需要准备转以下工具:

  • GNU autoconf
  • GNU automake
  • GNU libtool
  • GNU m4

以上这些都可以从 获取。

注:以上这些都是类 Unix 环境下才能使用的工具。

二、与 UNIX 构建系统交互: config.m4

扩展的 config.m4 文件告诉 UNIX 构建系统哪些扩展 configure 选项是支持的,你需要哪些扩展库,以及哪些源文件要编译成它的一部分。

改装一个已经存在的扩展

为了显示出创建一个独立的扩展是很容易的事情,我们先将一个已经内嵌到 PHP 的扩展改成独立扩展。安装 PHP 并且执行以下命令:

$ mkdir /tmp/newext
$ cd /tmp/newext

现在你已经有了一个空目录。我们将 mysql 扩展目录下的文件复制过来:

$ cp -rp php-4.0.X/ext/mysql/* .
# 注:看来这篇 README 真的需要更新一下了
# PHP7 中已经移除了 mysql 扩展部分

到这里扩展就完成了,执行:

$ phpize

现在你可以独立存放这个目录下的文件到任何地方,这个扩展可以完全独立存在了。

用户在编译时需要使用以下命令:

$ ./configure 
       [--with-php-config=/path/to/php-config] 
       [--with-mysql=MYSQL-DIR]
$ make install

这样 MySQL 模块就可以使用内嵌的 MySQL 客户端库或者已安装的位于 MySQL 目录中的 MySQL。

注:意思是说想要编写 PHP 扩展,你既需要已经安装了 PHP,也需要下载一份 PHP 源码。

autoconf 语法简介

config.m4 文件使用 GNU autoconf 语法编写。简而言之,就是用强大的宏语言增强的 shell 脚本。注释用字符串 dnl 分隔,字符串则放在左右方括号中间(例如,[ 和 ])。字符串可按需要多次嵌套引用。

定义一个新扩展

我们给示例扩展命名为 “foobar”。

新扩展包含两个资源文件:foo.c 和 bar.c(还有一些头文件,但这些不只重要)。

示例扩展不引用任何外部的库(这点很重要,因为这样用户就不需要特别指定一些编译选项了)。

LTLIBRARY_SOURCES 选项用于指定资源文件的名字,你可以有任意数量的资源文件。

注:上面说的是 Makefile.in 文件中的配置选项,可以参考 xdebug。

根据需要修改config.m4

  1. 切换到ext/edutest1/目录。
  2. vi config.m4
  3. 将下面的第一、三行取消注释,并删掉第二行:
16 dnl PHP_ARG_ENABLE(edutest1, whether to enable edutest1 support,
 17 dnl Make sure that the comment is aligned:
 18 dnl [  --enable-edutest1           Enable edutest1 support])

修改为:

16 PHP_ARG_ENABLE(edutest1, whether to enable edutest1 support,
 17     [  --enable-edutest1           Enable edutest1 support])
  1. PHP_SUBST一行的注释打开:
19 if test "$PHP_EDUTEST1" != "no"; then
……
59   PHP_SUBST(EDUTEST1_SHARED_LIBADD)
60
61   PHP_NEW_EXTENSION(edutest1, edutest1.c, $ext_shared)
62 fi

简要说明: