windows 编译 php 扩展

老刘

Windows 编译 PHP 扩展:从零到可用的完整教程

目标关键词:Windows 编译 PHP 扩展

在 Windows 环境下编译 PHP 扩展,很多人第一反应就是“麻烦、容易报错、环境难配”。确实,相比 Linux,Windows 下的 PHP 扩展编译门槛更高,但只要把环境搭对,流程其实是固定的。本文就围绕 Windows 编译 PHP 扩展 这个主题,按“问题分析 → 解决方案 → 注意事项”的结构,讲清楚从准备环境到成功生成 .dll 扩展文件的全过程,适合新手按步骤操作,也适合有经验的人直接对照排坑。


一、问题分析:为什么 Windows 下编译 PHP 扩展这么容易失败?

PHP 扩展本质上是一个动态库文件。
在 Linux 下通常是 .so,在 Windows 下则是 .dll。编译 PHP 扩展,不只是“装个编译器然后点一下编译”这么简单,它要求:

  1. PHP 版本必须匹配

    • 例如你用的是 PHP 8.1,就不能拿 PHP 7.4 的扩展源码直接编。
    • 线程安全版(TS)和非线程安全版(NTS)也不能混用。
  2. 编译工具链必须匹配

    • Windows 下通常要用 Visual Studio + MSVC
    • PHP 官方预编译包对应的编译器版本必须一致。
  3. PHP 源码和头文件要齐全

    • 编译扩展时需要 phpize 类似的准备过程。
    • Windows 下要使用官方 SDK、头文件、构建脚本。
  4. 依赖库版本要一致

    • 扩展如果依赖 OpenSSL、libcurl、zlib、libxml 等库,版本不一致就会报链接错误。
  5. 环境变量和路径容易出问题

    • cl.exenmakecmakephp.exephpize 所在目录找不到,编译会直接失败。

所以,Windows 下编译 PHP 扩展的核心不是“会不会写代码”,而是 环境、版本、工具链三者是否完全匹配


二、解决方案:Windows 编译 PHP 扩展的标准流程

下面以常见的 Windows 开发环境为例,讲清楚完整流程。这里默认你是要编译一个 PHP 原生扩展,不是 Composer 包,也不是 PHP 脚本。


方案一:使用 PHP 官方 SDK + Visual Studio 编译

这是最常见、最正规的一种方式。


第一步:确认你的 PHP 版本和类型

先查看你当前 PHP 的信息,重点看这几个参数:

php -v
php -i | findstr "Thread Safety"
php -i | findstr "Architecture"
php -i | findstr "Compiler"

你需要确认:

  • PHP 版本号:比如 8.1.12、8.2.10
  • 线程安全:TS 还是 NTS
  • 架构:x64 还是 x86
  • 编译器:例如 Visual C++ 2019 / 2022

这些信息非常重要,因为扩展必须和 PHP 主程序匹配。


第二步:安装 Visual Studio 编译环境

建议安装:

  • Visual Studio 2022
  • 勾选 使用 C++ 的桌面开发
  • 同时安装:
    • MSVC 编译工具
    • Windows 10/11 SDK
    • CMake 工具(有些项目会用到)

如果你只想轻量一点,也可以安装:

  • Build Tools for Visual Studio 2022

安装后,打开:

  • x64 Native Tools Command Prompt for VS 2022

这个命令行窗口里已经帮你配置好了 cl.exenmake 等编译工具环境。


第三步:下载匹配的 PHP 开发包

不要直接拿你本机的 PHP 安装目录硬编,最好下载对应版本的开发包。

你需要准备:

  • PHP 对应版本的源码或开发包
  • 和当前 PHP 版本一致的头文件
  • 匹配的 phpize / build 文件

如果你在编译第三方扩展,通常扩展源码目录里会带:

  • config.w32
  • php_*.h
  • *.c
  • *.m4 或 Windows 平台构建文件

Windows 下更常见的是 config.w32 方案。


第四步:准备扩展源码

假设你要编译的扩展目录如下:

myext/
├─ config.w32
├─ php_myext.h
├─ myext.c
├─ myext_arginfo.h
├─ package.xml
└─ ...

你需要确认这个扩展本身支持 Windows 编译。
如果源码只写了 Linux 的 config.m4,那在 Windows 上不能直接用,通常需要额外适配 config.w32


第五步:配置 PHP 扩展编译环境

Windows 下常见的做法是使用 php-sdk-binary-tools 或者官方推荐的构建环境。

一般流程是:

  1. 安装 PHP SDK 工具包
  2. 设置源码目录
  3. 设置目标 PHP 版本目录
  4. 运行 buildconf 或相关脚本
  5. 生成编译项目
  6. 使用 nmake 编译

不同 PHP 版本和扩展项目,脚本略有差异,但核心思路一致。


第六步:编译扩展

如果扩展项目已经适配好 Windows,常见步骤会类似下面这样:

方式 1:使用 configure / nmake 流程

进入扩展源码目录后,运行类似命令:

phpize
configure --enable-myext
nmake
nmake test

但要注意:
Windows 原生环境下不一定有标准的 phpize,这更常见于类 Unix 环境。
在 Windows 下,很多时候是通过 config.w32 + buildconf + nmake 完成。


方式 2:使用 config.w32

如果扩展目录下有 config.w32,通常会这样操作:

  1. 打开开发者命令行
  2. 进入 PHP 源码或扩展构建环境
  3. 执行生成配置
  4. 执行编译命令

常见结果是生成:

  • php_myext.dll

编译成功后,把这个 DLL 放到 PHP 的 ext 目录。


第七步:启用扩展

编译完成后,编辑 php.ini,加入:

extension=myext.dll

如果扩展 DLL 放在 ext 目录下,通常这样写就行。
如果 DLL 不在默认扩展目录,可以写绝对路径:

extension="D:\php\ext\myext.dll"

然后重启 Web 服务或命令行重新打开 PHP,检查是否加载成功:

php -m

或者:

php -i | findstr myext

如果能看到扩展名称,说明加载成功。


三、实战示例:编译一个简单的 PHP 扩展

下面给一个更贴近实战的思路,方便理解整个过程。


示例目标

编译一个名为 myext 的 PHP 扩展,功能是提供一个简单函数:

echo myext_hello();

返回:

Hello Windows PHP Extension

第一步:准备扩展代码

扩展代码一般包括:

  • 扩展入口
  • 函数声明
  • 模块初始化
  • 头文件

如果你是自己写扩展,最少要确保:

  1. 有正确的函数签名
  2. MINITMSHUTDOWNRINITRSHUTDOWN
  3. 导出模块信息

第二步:确认 PHP API 版本一致

编译扩展时,最容易踩坑的是 API 不匹配。
例如:

  • php8ts.dll 对应 TS 版本
  • php8.dll 对应 NTS 版本

如果你拿 TS 版 PHP 去加载 NTS 版扩展,或者反过来,通常会直接报错:

  • The specified module could not be found
  • Unable to load dynamic library
  • PHP Startup: Unable to load dynamic library

这类错误不一定是文件真的找不到,很多时候是 依赖或版本不匹配


第三步:检查依赖 DLL

如果扩展依赖其他库,比如:

  • libssl-3-x64.dll
  • libcrypto-3-x64.dll
  • zlib1.dll
  • libxml2.dll

这些 DLL 也必须存在于:

  • PHP 安装目录
  • 系统 PATH
  • 扩展 DLL 同目录

否则扩展加载时会失败。


四、常见报错与排查方法

Windows 编译 PHP 扩展,最常见的问题基本就这些。


1. cl.exe 找不到

原因

没有打开 Visual Studio 开发者命令行,或者 C++ 工具没有安装完整。

解决方法

  • 打开 x64 Native Tools Command Prompt for VS 2022
  • 检查安装了 使用 C++ 的桌面开发
  • 在命令行执行:
cl

如果能显示版本信息,说明环境正常。


2. nmake 不是内部或外部命令

原因

没有加载 VS 编译环境。

解决方法

  • 使用 Visual Studio 提供的开发者命令行
  • 或者手动执行环境脚本后再编译

3. Unable to load dynamic library

原因

常见有以下几种:

  • DLL 不是当前 PHP 版本编译的
  • TS/NTS 不匹配
  • x64/x86 不匹配
  • 依赖 DLL 缺失
  • 扩展名写错
  • php.ini 路径配置错误

解决方法

逐项检查:

  1. php -v 看版本
  2. php -i | findstr "Thread Safety" 看 TS/NTS
  3. php -i | findstr "Architecture" 看架构
  4. 检查 DLL 是否放在正确目录
  5. Dependencies 工具查看缺失依赖

4. 编译时报头文件找不到

原因

PHP 开发头文件路径没配好,或者源码目录不完整。

解决方法

确认包含以下内容:

  • php.h
  • zend.h
  • ext/standard/info.h
  • 对应扩展依赖头文件

如果是第三方扩展,确保源码树完整,不要只下载了单个 .c 文件。


5. 链接错误、符号未定义

原因

函数声明和实现不一致,或者调用了未正确导出的库。

解决方法

  • 检查函数原型
  • 确认导出宏是否正确
  • 检查链接库是否匹配 32/64 位
  • 检查是否用了不兼容的编译选项

五、推荐的新手方案:先用现成扩展,再考虑自己编译

如果你是电脑小白,建议先按这个顺序来:

第一步:先找现成 DLL

很多 PHP 扩展在 Windows 下已经有预编译版本,比如:

  • redis
  • xdebug
  • imagick
  • mysqli
  • grpc
  • ssh2

如果官方或第三方已经提供了适配你 PHP 版本的 DLL,优先直接下载使用。

第二步:确认匹配关系

下载时重点看:

  • PHP 版本
  • TS/NTS
  • x64/x86
  • VC 编译版本

第三步:再考虑自己编译

只有在以下情况才建议自己编译:

  • 没有现成版本
  • 需要修改扩展源码
  • 需要适配特殊库
  • 想学习 PHP 扩展开发

这样能少踩很多坑。


六、进阶方案:用 Docker 或 WSL 降低编译难度

如果你的目标不是“必须在 Windows 原生编译”,而是“把扩展跑起来”,那可以考虑更省事的方案。


方案 A:WSL

在 Windows 上安装 WSL,然后在 Linux 环境下编译 PHP 扩展。
优点是:

  • 编译环境更接近 Linux 原生流程
  • phpizeconfiguremake 更顺手
  • 适合很多开源扩展

缺点是:

  • 最终生成的是 Linux 的 .so
  • 不能直接给 Windows PHP 用

方案 B:Docker

如果你只是为了开发、测试、部署到 Linux 服务器,可以直接用 Docker 搭环境。

优点:

  • 环境干净
  • 依赖隔离
  • 重现性好

缺点:

  • 同样不直接生成 Windows 的 .dll

如果你的目标是 Windows 本机 PHP 环境,那还是得走 Windows 原生编译链。


七、注意事项:编译成功前必须检查的细节

下面这些点,建议你动手前先确认。


1. PHP 版本必须完全一致

不要只看大版本,比如“都是 PHP 8”,这还不够。
最好精确到小版本,尤其是:

  • 8.1.x
  • 8.2.x
  • 8.3.x

很多扩展对小版本 API 也有要求。


2. TS 和 NTS 不能混用

这是 Windows 下最常见的坑之一。

  • TS:线程安全版
  • NTS:非线程安全版

Apache 模式下很多情况下要用 TS,
而 IIS/FastCGI 或命令行常见 NTS。


3. 32 位和 64 位必须一致

x86 的 PHP 只能加载 x86 扩展,
x64 的 PHP 只能加载 x64 扩展。

这条看起来简单,但非常容易忽略。


4. 运行库要匹配

Windows 扩展经常依赖 Visual C++ 运行库。
如果系统缺少对应版本的 VC Runtime,也会导致扩展加载失败。

建议安装:

  • Visual C++ Redistributable 2015–2022 x64
  • 如有需要再装 x86 版本

5. 用文本编辑器检查 php.ini

很多人扩展明明编译好了,却因为 php.ini 写错导致没加载。

正确做法:

  • 确认 extension_dir 指向正确目录
  • 扩展名写对
  • 注释符号没有保留
  • 修改后重启服务

示例:

extension_dir="D:\php\ext"
extension=myext.dll

八、排错顺序:遇到问题先按这个流程查

如果你编译或加载失败,建议按下面顺序排查:

  1. 确认 PHP 版本

    • php -v
  2. 确认线程安全

    • php -i | findstr "Thread Safety"
  3. 确认架构

    • php -i | findstr "Architecture"
  4. 确认编译器

    • cl
    • nmake
  5. 确认 DLL 位置

    • 是否放在 ext 目录
  6. 确认 php.ini 配置

    • extension_dir
    • extension=xxx.dll
  7. 检查依赖 DLL

    • 使用 Dependencies 工具查看缺失项
  8. 检查日志

    • PHP 错误日志
    • Web 服务器日志
    • Windows 事件查看器

九、适合新手的最稳妥建议

如果你第一次接触 Windows 编译 PHP 扩展,最稳妥的做法是:

  1. 先确认你本机 PHP 版本、TS/NTS、x64/x86
  2. 安装 Visual Studio 2022 和 C++ 组件
  3. 找到和 PHP 完全匹配的扩展源码或预编译包
  4. 先尝试加载现成 DLL,确认环境无误
  5. 再进入源码编译
  6. 编译后立刻用 php -m 验证
  7. 如果失败,优先查版本和依赖,不要先怀疑代码

这样能把排错时间缩到最短。


十、总结

Windows 编译 PHP 扩展的关键,不是“会不会写扩展代码”,而是 环境、版本、架构、运行库、依赖 这五件事必须全部匹配。只要把这些基础工作做扎实,编译流程其实是很稳定的。

最核心的几条记住就够了:

  • PHP 版本一致
  • TS/NTS 一致
  • x64/x86 一致
  • Visual Studio 编译环境准备好
  • 依赖 DLL 不能缺
  • php.ini 配置要正确

只要按步骤走,Windows 下编译 PHP 扩展并没有想象中那么难。真正难的地方,往往不是编译命令本身,而是前期环境没对齐。

文章版权声明:文章内容均来源于各大短视频平台搜集以及修改和删减新增,如有侵权或者违规,请联系站长进行删除,如需转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
验证码
评论列表 (暂无评论,3人围观)

还没有评论,来说两句吧...

目录[+]