在Windows平台上开发和编译PHP扩展成DLL文件的详细指南

概述

在Windows平台上开发和编译PHP扩展成DLL文件的详细指南

我通常在Linux系统上开发php扩展,扩展是通过编译安装添加的。然而,在开发php-opencv扩展时,有扩展用户问我是否可以提供窗口扩展dll参考文件。所以最近一直在考虑支持window平台,总结一下自己在Windows下开发PHP扩展并编译成DLL的经验。

官方文档

事实上,PHP官方提供了扩展编译成window.dll的官方文档。当时没有仔细看官方文档,所以捣鼓了几天。

1.环境准备

这里我想详细说一下环境。官方文件中提到的环境要求。 Visual Studio环境可以直接用Visual Studio ide安装。我一直以为它指的是Visual Studio C++,所以运行phpsdk-vc15-x64时,会出现Could not deternine。 ‘vc15’目录错误,PHP编译成DLL的环境可以使用此IDE安装

1.1安装Visual Studio(IDE)

前往官网下载Visual Studio Install

1.2 添加编译环境

在Visual Studio Professional 2017下选择修改后,选择安装在相应的环境中

所需的环境已经准备好了。

2.编译前的准备,设置构建目录2.1 php-sdk-binary-tools

php-sdk-binary-tools是官方提供的工具。

1.下载php-sdk-binary-tools

git clone https://github.com/Microsoft/php-sdk-binary-tools
cd php-sdk-binary-tools

2. 调用启动脚本。比如这里是php7.2,对应的是64位版本的Visual Studio 2017,调用phpsdk-vc15-x64.bat。当你运行它时,你会发现cmd窗口的开头会变成一个$符号。

3. 运行 phpsdk_buildtree 批处理脚本,这将创建所需的目录结构:

phpsdk_buildtree phpdev

运行后会发现php-sdk-binary-tools中多了一个phpdev目录

phpsdk_buildtree脚本会根据当前使用的VC++版本创建路径并切换到新创建的目录

4. 将 PHP 源代码解压到:F:\www\php-sdk-binary-tools\phpdev\vc##\x##。在PHP源码解压的同一目录下,有一个deps目录。

5、进入解压后的php源码目录,运行phpsdk_deps -u或phpsdk_deps --update --branch master。 PHP会自动下载所需的依赖包(php7之前需要手动下载php-dsp文件)

3.编译php3.1并搭建配置好的环境

上面已经准备好了编译前的构建准备环境。在编译之前,调用 php-sdk-binary-tools 中的启动脚本自动设置所需构建配置的环境 phpsdk-vc15-x64.bat。

3.2 执行buildconf

切换到php源码根目录,执行buildconf命令。如果提示输入错误:没有文件扩展名“.js”的脚本引擎。

这里主要原因是系统安装IDE(Dreamwear、UltraEdit、EditPlus,我之前安装了phpstorm并修改过)后,修改了.js文件的默认打开方式。

当你想直接执行js脚本时就会出现这个错误。

按快捷键win+r,然后输入regedit,打开注册表编辑器,找到[HKEY_CLASSES_ROOT.js]项,双击默认值,将其更改为“JSFile”。如图所示:

然后就可以成功执行了

3.3 编译配置

执行以下命令编译php配置:

configure --disable-all  --enable-cli

注:您可以自行适当调整。可以使用configure --help查看参数,如:

configure --disable-all  --enable-cli --enable-debug --with-all-shared

执行成功后,会提示执行nmake。

执行此步骤将在主目录中生成config.w32.h文件。编译 PHP 扩展需要此文件,因此如果您正在编译 PHP 扩展,请执行下一步 nmake。如果您只是编译 PHP 扩展,则不需要执行`nmake。

3.4 执行nmake编译

然后执行nmake开始编译

等待几分钟后,您应该能够在 php-src 目录中找到一个多了一个编译位(x32 或 x64)的目录。目录下有一个Release_TS(或Release_NTS或Debug_TS)这样的目录。

如果编译正常,下面会出现一个php.exe文件,证明php文件编译成功。

运行编译好的php.exe -v 看看是否正常运行

4. 编译php扩展 4.1 创建php扩展

如果我们只编译一些已经打开的扩展源码,则不需要运行这一步。这里我们创建一个用于编译的演示扩展。

使用git bash进入源代码地址\ext目录并执行:

php.exe ext_skel_win32.php --extname==my_function

注意:这里之所以使用git bash工具,是因为git bash自带了模拟的Linux环境。 My_function 是我需要在此处创建的扩展。具体的可以根据自己的需要进行更改。

创建工具时,提示符“sh”不被识别为内部或外部命令,

git bash执行结果:

可以看到源码ext目录下多了一个my_function目录。这是我们刚刚使用 ext_skel_win32.php 命令创建的初始扩展代码。

4.2 修改源码

1.我们编辑my_function下的my_function.c文件。添加一个方法my_function_test方法,代码如下:

PHP_FUNCTION(my_function_test) {
   php_printf("This is my function PHP extension! \n");
}

2. 然后将 PHP_FE(my_function_test, NULL) 添加到 const zend_function_entry my_function_functions[] 中,但放在 PHP_FE_END 之前:

4.3 编译扩展

切换回cmd窗口

1、进入php-sdk-binary-tools目录,使用phpsdk-vc15-x64.bat

2.切换到php源代码目录,运行buildconf

3、如果执行buildconf后执行configure命令,会提示类似如下错误:

打开提示文件,找到对应的行号,发现末尾多了多余的注释符号。这可能是工具问题,

解决方案:打开扩展源码的config.w32,找到注释 // 否则,使用ARG_ENABLE,将其删除,然后重新运行buildconf。注意:

运行configure --help,你会发现额外的--enable-my_function选项:

4. 运行configure --disable-all --enable-cli --enable-my_function=shared进行编译配置:

发现错误信息:

F:\www\php-sdk-binary-tools\phpdev\vc15\x64\php-7.2.12-src\configure.js(5490, 2) Microsoft JScript 运行时错误: 'PHP_EXTNAME_SHARED' 未定义

解决方案:重新打开扩展的config.w32文件,删除下面的图片,PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"

重启buildconf->运行编译配置命令。可以看到编译配置成功,提示启用扩展:我们的扩展已添加:

5. 运行nmake命令进行编译。等待几分钟到十分钟后,如果终端出现类似下面的信息:Compilation success,则表示编译成功。

而且我在源代码目录中发现了一个额外的x64目录。如果编译是32位的话就是x86。

里面有一个Release_TS(release表示non-debug,对应debug,TS表示线性安全,对应NTS),

里面的文件就是我们编译的php文件,我们发现php_my_function.dll文件就是我们编译的扩展文件。

6.配置php.ini引用编译后的扩展

进入编译目录,运行php.exe -v 测试编译是否正常。

当你运行php.exe --ini命令时,你会发现没有配置文件,当你运行php.exe -m时,你会发现PHP Modules中没有我们创建的my_function扩展模块。

将源码中的php.ini-development复制到编译目录下,改名为php.ini,然后修改原来的php.ini文件:

; On windows:
; extension_dir = "ext"

更改为:

; On windows:
extension_dir = "./"

和:

再次运行 php -m test

7.测试并添加测试文件test.php


my_function_test();

然后运行编译好的php目录\php.exe test.php

至此,window下编译php及php扩展已经成功。

清理干净

nmake clean 命令会清除编译后的文件,但不会删除目录和php.ini。

当修改只是修改扩展名时,不要运行nmake clean命令。只需要中央configure和nmake分别重新编译修改后的扩展,而不需要使用整个PHP扩展。这样可以大大提高开发扩展的效率。我不知道我之前已经运行过nmake。 clean命令,每次扩展修改一点代码,都要等10多分钟才能得到结果。

迭代参考

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

53阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

45阅读

php一句话木马,一句话木马ctf

2026年10月05日

48阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

50阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

47阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

42阅读