编译PHP扩展的方法-php教程

资源魔 44 0

【相干学习保举:php编程(视频)】

构建PHP扩大

你曾经晓得若何去编译PHP自身,下一步咱们将编译内部扩大。咱们将探讨扩大的构建进程以及可用的编译选项。

载入同享扩大

正在前一个章节你曾经晓得,PHP 扩大既能构建成动态库也能够构建成静态库(.so)。年夜少数动态库是与 PHP 绑缚正在一同编译的,静态库能够显式地通报参数 --enable-EXTNAME=shared--with-EXTNAME=shared./configure

动态扩大默许是可用的,静态库需求添加 extension 或许 zend_extension 的 ini 设置装备摆设。俩者能够是相对门路,也能够是绝对门路。

例如编译 PHP 扩大用名目的设置装备摆设项:

~/php-src> ./configure --prefix=$HOME/myphp
                       --enable-debug --enable-maintainer-zts
                       --enable-opcache --with-gmp=shared

这个例子中 opcache 扩大以及 GMP 扩大都被编译为位于 modules/ 目次中的同享工具。 您能够经过更改extension_dir或经过通报相对门路来加载:

~/php-src> sapi/cli/php -dzend_extension=`pwd`/modules/opcache.so
                        -dextension=`pwd`/modules/gmp.so
# or
~/php-src> sapi/cli/php -dextension_dir=`pwd`/modules
                        -dzend_extension=opcache.so -dextension=gmp.so

正在 make install 步骤中,这两个 .so 文件会被移进 PHP 装置的扩大目次,你应用 php-config --extension-dir 饬令可能能够找到它。关于下面的构建选项,它将是 /home/myuser/myphp/lib/php/extensions/no-debug-non-zts-MODULE_API。这个值也是 extension_dir 设置装备摆设选项的默许值,以是你无需明白地指定它,就能够间接加载进扩大:

~/myphp> bin/php -dzend_extension=opcache.so -dextension=gmp.so

这给咱们留下了一个成绩:你应该应用哪一种机制?同享工具使你有一个根本的 PHP 二进制文件并经过 php.ini 加载其余扩大。刊行版经过原始的 PHP 软件包以及将扩大作为独自的软件包散发来行使此性能。另外一方面,假如你编译本人的 PHP 二进制文件,则可能没有需求这个,由于你曾经晓得需求哪些扩大。

依据经历,你将对 PHP 自身绑缚的扩大应用动态链接,并将同享扩大用于其余中央。缘由很简略,就像你稍后看到的,构建内部扩大为同享工具的更易(或至多缩小了侵入性)。另外一个益处是你能够正在不必从新构建 PHP 的状况下更新扩大。

留意

假如你需求无关扩大以及 Zend 扩大之间差别的信息,你能够查阅专门章节。

从 PECL 装置扩大

PECL,PHP 扩大社区库,提供了年夜量的 PHP 扩大。当扩大从主 PHP 刊行版中删除了,它们通常还正在 PECL中。一样,如今与 PHP 绑缚一同的许多扩大之前都是 PECL 扩大。

除了非你正在 PHP 构建的设置装备摆设步骤指定 --without-pear,不然 make install 将PECL 作为 PEAR 的一局部下载并装置。你能够正在 $PREFIX/bin 目次下找到 pecl 剧本。如今装置扩大很简略,就像运转 pecl install EXTNAME 同样,例如:

~/myphp> bin/pecl install apcu

该饬令将下载、编译并装置 APCu 扩大。后果会是 apcu.so 文件正在扩大目次下,能够经过通报 extension=apcu.so 设置装备摆设选项来加载此文件。

尽管 pecl install 对终端用户十分不便,但扩大开发职员对它没甚么兴味。正在上面,咱们将会阐明两种手动构建扩大的形式:经过将其导入次要的 PHP 源码树(容许动态链接)或经过内部构建(仅同享)。

增加扩大到 PHP 源码树

第三方扩大以及绑缚正在 PHP 的扩大之间不基本上的区分。因而你能够经过复制内部扩大到 PHP 源码树,并以及通常的构建进程同样来构建。咱们以APCu 作为例子来演示。

起首,你要把扩大的源代码放到 PHP 源码树的 ext/EXTNAME 目次。假如扩大可经过 Git 取得,就像从 ext/ 中克隆仓库同样简略:

~/php-src/ext> git clone https://github.com/krakjoe/apcu.git

或许你也能够下载源码紧缩包并解压它:

/tmp> wget http://pecl.php.net/get/apcu-4.0.2.tgz
/tmp> tar xzf apcu-4.0.2.tgz
/tmp> mkdir ~/php-src/ext/apcu
/tmp> cp -r apcu-4.0.2/. ~/php-src/ext/apcu

该扩大会蕴含一个 config.m4 文件,该文件指定autoconf文件应用的特定扩大构建指令。 为了将它们蕴含正在 /configure 剧本,你必需再次运转 ./buildconf。为了确保设置装备摆设文件曾经从新天生,倡议事前删除了它:

~/php-src> rm configure && ./buildconf --force

如今你能够应用 ./config.nice 剧本将 APCu 增加到你的现有设置装备摆设,或许从全新的设置装备摆设行开端:

~/php-src> ./config.nice --enable-apcu
# or
~/php-src> ./configure --enable-apcu # --other-options

最初,运转 make -jN 执行实际的构建。因为咱们不应用 --enable-apcu=shared,该扩大曾经动态链接到 PHP 库,即没有需求额定的操作便可应用它。显然,你也能够应用 make install 去装置最初的二进制文件。

应用 phpize 构建扩大

还能够经过应用构建 PHP章节说起到的 phpize 剧本与 PHP 离开构建。

phpize 的作用与 ./buildconf 用于 PHP 构建的剧本类似:第一,经过$PREFIX/lib/php/build 复制文件导入 PHP 构建零碎到你的扩大中。这些文件是 acinclude.m4(PHP 的 M4宏)、phpize.m4(它会正在你的扩大中重定名为 configure.in 并蕴含次要的构建阐明)以及 run-tests.php

而后 phpize 将挪用 autoconf 天生 ./configure 文件,该文件能够自界说扩大构建。留意,没须要通报 --enable-apcu 给它,由于这是隐式假设的。相同,你应该应用 --with-php-config 指定你的 php-config 剧本门路:

/tmp/apcu-4.0.2> ~/myphp/bin/phpize
Configuring for:
PHP Api Version:         20121113
Zend Module Api No:      20121113
Zend Extension Api No:   220121113

/tmp/apcu-4.0.2> ./configure --with-php-config=$HOME/myphp/bin/php-config
/tmp/apcu-4.0.2> make -jN && make install

当你构建扩大时,你应该老是指定 --with-php-config 选项(除了非你只有一个全局的 PHP 装置),不然 ./configure 无奈确定要构建的 PHP 版本以及标记。指定 php-config 剧本也确保了 make install 将挪动天生的 .so 文件(能够正在 modules/ 目次找到)到正确的扩大目次。

因为正在 phpize 阶段还复制了 run-tests.php 文件,因而你能够应用 make test(或显示挪用 run-tests)运转扩大测试。

删除了已编译工具的 make clean 也是可用的,而且容许你增量构建失败时强迫从新构建扩大。 另外 phpize 提供了一个清算选项 phpize --clean。该饬令将删除了一切 phpize 导入的文件以及经过 /configure 剧本天生的文件。

显示对于扩大的信息

PHP CLI 二进制文件提供了几个选项来显示对于扩大的信息。你曾经晓得 -m,该饬令会列出一切曾经下载的扩大。你能够行使它来确定扩大能否正确下载了:

~/myphp/bin> ./php -dextension=apcu.so -m | grep apcu
apcu

另有其余一些以 --r 扫尾的参数都是具备 Reflection 性能。例如,你能够应用 --ri 去显示扩大的设置装备摆设:

~/myphp/bin> ./php -dextension=apcu.so --ri apcu
apcu

APCu Support => disabled
Version => 4.0.2
APCu Debugging => Disabled
MMAP Support => Enabled
MMAP File Mask =>
Serialization Support => broken
Revision => $Revision: 328290 $
Build Date => Jan  1 2014 16:40:00

Directive => Local Value => Master Value
apc.enabled => On => On
apc.shm_segments => 1 => 1
apc.shm_size => 32M => 32M
apc.entries_hint => 4096 => 4096
apc.gc_ttl => 3600 => 3600
apc.ttl => 0 => 0
# ...

--re 参数列出扩大增加的一切初始设置、常数、函数以及类:

~/myphp/bin> ./php -dextension=apcu.so --re apcu
Extension [ <persistent> extension #27 apcu version 4.0.2 ] {
  - INI {
    Entry [ apc.enabled <SYSTEM> ]
      Current = '1'
    }
    Entry [ apc.shm_segments <SYSTEM> ]
      Current = '1'
    }
    # ...
  }

  - Constants [1] {
    Constant [ boolean APCU_APC_FULL_BC ] { 1 }
  }

  - Functions {
    Function [ <internal:apcu> function apcu_cache_info ] {

      - Parameters [2] {
        Parameter #0 [ <optional> $type ]
        Parameter #1 [ <optional> $limited ]
      }
    }
    # ...
  }
}

--re 参数仅实用一般扩大,Zend 扩大应用 --rz 替代。 你能够正在 opcache 上测验考试:

~/myphp/bin> ./php -dzend_extension=opcache.so --rz "Zend OPcache"
Zend Extension [ Zend OPcache 7.0.3-dev Copyright (c) 1999-2013 by Zend Technologies <http://www.zend.com/> ]

如你所见, 该饬令不显示有用的信息。由于 opcache 同时注册了一般扩大以及 Zend 扩大, 前者蕴含一切初始设置装备摆设、常量以及函数。因而正在这个非凡的案例中,你依然需求应用 --re。其余 Zend 扩大经过 --rz 可失去信息。

扩大 API 兼容性

扩大对5个次要要素十分敏感。假如它们没有合适,则该扩大将没有会加载到 PHP中,并将无用:

  • PHP Api 版本
  • Zend 模块 Api 编号
  • Zend 扩大 Api 编号
  • 调试模式
  • 线程平安

phpize 对象可以让你回忆它们的一些信息。以是,假如你正在调试模式下构建 PHP,并试图加载以及应用非调试模式构建的扩大,那它将无奈工作。其余反省也同样。

PHP Api 版本 是外部 API 版本号,Zend 模块 Api 编号 以及 Zend 扩大 Api 编号 辨别与 PHP 扩大以及 Zend 扩大 API 无关。

那些编号随后作为 C 宏通报给在构建的扩大,以便它自身能够反省那些参数,并正在 C 预解决器 #ifdef 的根底上采纳没有同的代码门路。当那些编号作为宏传给扩大代码,它们会被写正在扩大构造中,以便你每一次测验考试正在 PHP 二进制文件中加载该扩大时,都将对照 PHP 二进制文件自身的编号进行反省。假如没有婚配,那末该扩大没有会被加载,并显示一条谬误信息。

假如咱们看一下扩大的 C 构造,它看起来像这样:

zend_module_entry foo_module_entry = {
    STANDARD_MODULE_HEADER,
    "foo",
    foo_functions,
    PHP_MINIT(foo),
    PHP_MSHUTDOWN(foo),
    NULL,
    NULL,
    PHP_MINFO(foo),
    PHP_FOO_VERSION,
    STANDARD_MODULE_PROPERTIES
};

至今,对咱们来讲风趣的是 STANDARD_MODULE_HEADER 宏。假如咱们扩大它,咱们能够看到:

#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
#define STANDARD_MODULE_HEADER STANDARD_MODULE_HEADER_EX, NULL, NULL

留意 ZEND_MODULE_API_NOZEND_DEBUGUSING_ZTS 是若何应用的。

假如查看 PHP 扩大的默许目次,它应该像 no-debug-non-zts-20090626。如你所料,该目次由没有同的局部组成:调试模式,其次是线程平安信息,而后是Zend 模块 Api 编号。以是默许状况下,PHP 试图帮你阅读扩大。

留意

通常,当你成为一名外部开发职员或扩大开发职员,必需应用调试参数,而且假如必需解决 Windows 平台,线程也会显示进去。你能够针对那些参数的多种状况屡次编译同一扩大。
记住,每一次新的 PHP 次要/主要版本城市更改参数,比方 PHP Api 版本,这就是为何你需求针对新的 PHP 版本从新编译的缘由。

> /path/to/php70/bin/phpize -v
Configuring for:
PHP Api Version:         20151012
Zend Module Api No:      20151012
Zend Extension Api No:   320151012

> /path/to/php71/bin/phpize -v
Configuring for:
PHP Api Version:         20160303
Zend Module Api No:      20160303
Zend Extension Api No:   320160303

> /path/to/php56/bin/phpize -v
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226

留意

Zend 模块 Api 编号 自身是应用 年 月 日 的日期格局构建。这是 API 更改以及并被标志的日期。Zend 扩大 Api 编号 是 Zend 版本,其次是 Zend 模块 Api 编号

留意

数字太多?是的,一个 API 编号绑定一个 PHP 版本,对任何人来讲都足够了,而且能够简化对 PHP 的了解。可怜的是,除了了 PHP 版本自身,还添加了3种没有同的 API 编号。你应该找哪个?谜底是任何一个:当 PHP 版本演化时,它们三种同时演化。因为汗青缘由,咱们有三种没有同编号。

然而,你是一名 C开发职员,没有是吗?为何没有依据这些数字构建一个“兼容的”头文件?咱们正在咱们的扩大中应用了相似这些:

#include "php.h"
#include "Zend/zend_extensions.h"

#define PHP_5_5_X_API_NO            220121212
#define PHP_5_6_X_API_NO            220131226

#define PHP_7_0_X_API_NO            320151012
#define PHP_7_1_X_API_NO            320160303
#define PHP_7_2_X_API_NO            320160731

#define IS_PHP_72          ZEND_EXTENSION_API_NO == PHP_7_2_X_API_NO
#define IS_AT_LEAST_PHP_72 ZEND_EXTENSION_API_NO >= PHP_7_2_X_API_NO

#define IS_PHP_71          ZEND_EXTENSION_API_NO == PHP_7_1_X_API_NO
#define IS_AT_LEAST_PHP_71 ZEND_EXTENSION_API_NO >= PHP_7_1_X_API_NO

#define IS_PHP_70          ZEND_EXTENSION_API_NO == PHP_7_0_X_API_NO
#define IS_AT_LEAST_PHP_70 ZEND_EXTENSION_API_NO >= PHP_7_0_X_API_NO

#define IS_PHP_56          ZEND_EXTENSION_API_NO == PHP_5_6_X_API_NO
#define IS_AT_LEAST_PHP_56 (ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO && ZEND_EXTENSION_API_NO < PHP_7_0_X_API_NO)

#define IS_PHP_55          ZEND_EXTENSION_API_NO == PHP_5_5_X_API_NO
#define IS_AT_LEAST_PHP_55 (ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO && ZEND_EXTENSION_API_NO < PHP_7_0_X_API_NO)

#if ZEND_EXTENSION_API_NO >= PHP_7_0_X_API_NO
#define IS_PHP_7 1
#define IS_PHP_5 0
#else
#define IS_PHP_7 0
#define IS_PHP_5 1
#endif

瞥见了?

或许更简略(更好)的是应用 PHP_VERSION_ID ,这你可能更相熟:

#if PHP_VERSION_ID >= 50600

想理解更多编程学习,敬请存眷php培训栏目!

以上就是编译PHP扩大的办法的具体内容,更多请存眷资源魔其它相干文章!

标签: php开发教程 php开发资料 php开发自学 PHP扩展

抱歉,评论功能暂时关闭!