问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

window 怎么编译 php 扩展

发布网友 发布时间:2022-04-06 03:07

我来回答

2个回答

懂视网 时间:2022-04-06 07:29

【相关学习推荐: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培训栏目!

    热心网友 时间:2022-04-06 04:37

    win上已经编译好了。如图phpstudy集成包,在菜单php扩展里勾上相应的扩展,自动打开扩展。phpstudy 2014如图,支持php版本选择,iis和nginx等追答

    如何在Windows下配置搭建PHP环境

    3、在解压后的路径中找到php.ini-development,重命名为php.ini。首先打开php.ini,找到:; On windows:;extension_dir = "ext"修改为:; On windows:extension_dir = " E:/LAMP/php5.3/ext"即去掉extension_dir前面的分号(注意斜杠方向),表示指定PHP扩展包的具体目录,以便调用相应的DLL文件。

    在Windows系统下怎么部署PHP网站运行环境

    方法/步骤1、安装WAMP集成环境 通过上面"环境下载"链接下载WAMP后,将其解压至任意目录,然后双击开始安装。2、安装过程中,会提示选择默认浏览器,如果想要自己指定,需找到合适的浏览器,选中浏览器后,点击打开,程序会继续安装。3、安装完成后,打开Wamp,如果正运行正常,会显示绿色图标。可以通过右键图...

    windows如何安装phpWindows如何安装驱动

    2.首先,安装PHPManagerForIIS。安装成功后,IIS界面会出现更多的PHPManager图标,等待后续操作。3.解压下载的PHP7.0.2forwin,确定放置位置。我将它放在C驱动器的根目录下,并将其重命名为PHP7.0.2。可以根据自己的需求进行调整。4.将php.ini-development复制到c盘的windows文件夹下,重命名为PHP.ini...

    在window下搭建NexusPHP时出现如下错误

    上面已经提示你了找到config配置文件把权限改成rwx读写执行权限,然后把config中的 BASIC权限改成777就是linux下的读写执行权限 rwx,

    PHP Warning: PHP Startup:

    这个是php配置问题,你配置的时候加了 php_zip.dll 扩展,但是你的扩展路径设错了,你设的是相对 路径,在WINDOW 中,这种路径 不好用,如果你的php 是安装 在 d:/server/php中,那个你的这个 扩展路径应该设为 extension_dir = "D:/server/php/ext" 这样,绝对 路径才行。 这个是在php.ini...

    window.open("bb.php?a=0","main")这种情况下不能用 把main去掉它就在...

    文本如果需要链接的方式推荐以上这种。浮动框架一样有效。

    PHP Warning: PHP Startup: in Unknown on line 0,这是错在哪了?求高 ...

    这个是php配置问题,你配置的时候加了 php_zip.dll 扩展,但是你的扩展路径设错了,你设的是相对 路径,在WINDOW 中,这种路径 不好用,如果你的php 是安装 在 d:/server/php中,那个你的这个 扩展路径应该设为 extension_dir = "D:/server/php/ext" 这样,绝对 路径才行。 这个是在php.ini...

    解决PHPWord 中的 ProofErr 问题

    PHPWord 是 PHPOffice 中用于处理 OOXML/OpenXML、OpenDocument/ODF、RTF、HTML、PDF 等文件格式的 PHP 扩展。在最近的一个 OA 项目中,我们遇到了一个与替换占位符相关的问题。财务团队想要修改发票模版,将落款单位由固定值改为“我开户行”对应的公司名称。在替换操作后,发现只有特定占位符能被正确...

    如何再wamp 下安装多个版本的php

    1、下载要安装的PHP版本。既然是用WampServer,那当然是下载Window版本的ZIP包啦:http://windows.php.net。解压到 Wamp的安装目录\bin\php\php5.2.17。这里以5.2.17为例。2、进入 Wamp的安装目录\bin\php\php5.2.17 目录,从 php.ini-dist 或者 php.ini-recommended 复制一份,重命名为php...

    linux和window分开装php和mysql和apache,安装包都是一样的吗,还是分...

    两个系统分开装,安装方式跟版本都是不一样的 最起码php里面的扩展都是dll的,liunx不可能解析的么

    windows扩展屏幕怎么用 win10新加卷怎么扩展 window扩展屏幕 window10扩展屏幕 windows扩展屏幕 window10扩展屏幕快捷键 为什么php不需要编译 为什么必须编译安装php php7编译安装gd库
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    四川省宜宾市工业工学校收费标准如何 你心目中最理想的大学是什么样子呢? 女生心目中理想的大学应该是怎样的? ...东西再去跑呢?还是空腹跑?谢谢了。我希望达到健康,减脂的效果_百度... 英语高手来看看!江湖救急! 急!英语问答高手来,多谢。 英语高手来~~~急~在线等~·介词短语作地点状语如果代词主语还完全倒装... 急!英语高手来下。 北京现在豆腐多少钱一斤? 现在豆腐多少钱一斤??? 如何写php扩展 什么时候会用到python装饰器 python函数中的装饰器有何用途? 也谈python装饰器为什么需要两层嵌套 如何PHP登录WebQQ上QQ 谁懂使用ThinkPHP 的 QQ第三方登录 qq第三方授权登录(PHP),发表腾讯微博,参数怎么传!?!?!!? 如何用php网页开启QQ Thinkphp 3.1.3怎么做第三方QQ登陆? php系统网站怎么设置QQ一键登录啊,要把放哪里呀 怎么制作 用QQ登陆网站 phpwind如何添加QQ登陆 [PHP] 用户登录 仿照 QQ客户端一样能否行?[高手支招] PHP模拟登陆QQ空间 php网站集成QQ登陆功能 php 绑定qq登陆 JSP、PHP网站是怎么实现:使用QQ登录本网站 php可以连接服务器执行脚本登陆qq吗,具体怎么做? 设置了权限的视频怎样下载 php有没有在服务器上从远程url下载的功能 怎样用c来编写php的扩展 如何在windows环境下编译生成PHP的zookeeper扩展dll 如何写一个PHP扩展 gearman怎么在windows上编译php扩展 C#net能开发编译php扩展吗 PHP的扩展模块怎么添加? 如何重新编译PHP使其支持mysqli 如何利用nginx配置https自签名证书 怎么生成https 如何添加自签名SSL证书? 小程序https自签名证书可以使用吗 请教下,网站可以部署https自签名证书吗? 如何配置https客户端 自认证证书 没有接触过PHP框架的人先学ThinkPHP好还是Yii好 关于开发框架的选择,thinkphp和yii选择哪个比较好 CI和YII框架,哪一个好 php框架学laravel和yii哪个好一些 关于YII框架和DEDECMS系统的思路问题 如何快速理解yii 1.1 框架 最好用的框架是哪个?CI,YII,rails,thinkphp哪个好?