Windows 环境下开发并编译 PHP C 扩展完整指南

Chloe
Chloe
发布时间:2026-10-15| 5人浏览过
原创

在 Windows 环境中为 PHP 编写自定义 C 扩展,需要结合 Visual Studio (VC++)、Cygwin 以及 PHP 源代码树进行构建。通过配置编译器路径、利用 ext_skel 脚本快速搭建骨架、调整工程链接选项,即可生成可用于生产环境的 .dll 动态库。本文将逐步拆解从准备环境到最终加载扩展的各个环节。

开发环境准备

要成功编译 PHP 扩展,必须确保计算机上安装了以下基础组件,并正确设置了相关路径:

  1. Cygwin:用于提供 make 等类 Unix 工具链。假设安装路径为 e:\app\cygwin。
  2. Visual Studio C++:推荐使用稳定的版本(如 VS 2010/2012/2015 等较新版本,原文提及的 VS6 已过时且不再支持现代 SDK)。需安装对应的 C/C++ 编译器组件。
  3. PHP 源代码包:下载与您目标运行版本一致的 PHP 源码包。假设解压目录为 e:\c_source_code\php-5.2.5。注意:源码版本需与您本地安装的 PHP 大版本保持一致。
  4. PHP 二进制目录:将已安装的 PHP 路径(例如 e:\app\php5.2.5)添加到系统的环境变量 PATH 中,以便命令行能直接调用 php.exe。

第一步:配置骨架生成器路径

PHP 源码中提供了一个名为 ext_skel_win32.php 的辅助脚本,用于自动生成本地扩展的文件结构。首先需要修改该脚本以指向正确的 Cygwin 路径。

  • 打开文件:PHP源文件目录/ext/ext_skel_win32.php(例如 E:\c_source_code\php-x.x.x\ext\ext_skel_win32.php)。
  • 找到定义 Cygwin 路径的变量 $cygwin_path,将其修改为您的实际安装路径:
$cygwin_path = 'e:\app\cygwin\bin'; // 请根据实际路径修改

第二步:生成扩展骨架代码

在 ext 目录下执行骨架生成命令。此步骤会创建一个新的文件夹,包含扩展的基本文件结构和头文件。

  1. 打开命令行终端,进入 e:\c_source_code\php-x.x.x\ext 目录。
  2. 运行命令:
php ext_skel_win32.php --extname=foo

执行成功后,会在当前目录下生成一个名为 foo 的新目录,其中包含了 config.w32.h、foo.c、foo.def 等必要文件。

第三步:添加链接库文件

为了让生成的扩展能够正确链接 PHP 的核心函数,需要将 PHP 运行时库拷贝到扩展目录中。

  • 找到 PHP 源码或安装目录下的 dev 文件夹。
  • 将 php5ts.lib(对应线程安全版)或 php5ts.lib(根据您的 php.ini 配置选择)复制到刚创建的 ext/foo 目录中。

第四步:编写扩展业务逻辑

使用编辑器打开 ext/foo/foo.c 文件。这是扩展的主要实现文件。您可以在其中:

  • 查找注释标记位置(通常提示在哪里添加用户自定义函数)。
  • 使用 PHP_FUNCTION(foo) 宏声明新的 PHP 可调用的函数。
  • 在 foo_methods[] 数组中添加函数的方法定义映射。

此处需要根据实际需求填充具体的 C 语言代码逻辑。

第五步:配置 Visual Studio 工程

这一步是将 C 代码编译为 DLL 的关键。请使用 Visual Studio 打开对应的工程文件(通常为 .dsp 格式或使用新式解决方案文件的 .vcxproj)。

  1. 打开工程:进入 ext/foo 目录,用 VC++ 打开 foo.dsp 或相应的工程文件。
  2. 调整工程配置:
    • 点击菜单 组建 (Build) → 移除工程配置 (Remove Configuration)。
    • 取消勾选 Win 32 Debug_TS(如果不需要调试)或保持 Win 32 Release_TS 作为活动配置。建议统一使用 Release_TS(Thread Safe Release)以保证性能与稳定性。
    • 在菜单栏选择 工程 (Project) → 设置 (Settings)(旧版 VC)或在属性页中选择 Win 32 Release_TS。
  3. 配置链接器参数:
    • 切换到 连接 (Link) 标签页。
    • 在“输出文件名”一栏,确认输出路径和名称(默认应为 foo.dll)。
  4. 配置预处理器定义:
    • 切换到 C/C++ 标签页。
    • 在“预处理器定义”中,增加 COMPILE_DL_FOO(注意全大写,且末尾替换为您的扩展名,例如 COMPILE_DL_BAR)。这告诉 PHP 扩展的动态链接机制。
    • 关键操作:务必取消选中 ZEND_DEBUG 或类似影响 ZEND 宏定义的选项(原文提到的 LIBZEND_EXPORTS 是旧版概念,在新版 SDK 中通常涉及避免符号冲突的配置,若遇到 undefined reference to ZEND 相关错误,需检查 include 路径是否包含正确的 ZEND_API 定义)。更通用的做法是确保在 Release 模式下不导出 PHP 内部符号,仅导入。

风险提示:编译前的环境配置至关重要。若 VC++ 找不到 php.h 或 zend.h,请务必在 IDE 的“包含目录”中加入 PHP 源码的根目录及 main、Zend 子目录。错误的配置会导致大量链接错误。

第六步:编译与验证

完成上述设置后,执行编译操作(Build Solution)。若一切顺利,将在输出目录生成 foo.dll 文件。

  1. 部署 DLL:将生成的 foo.dll 复制到您 PHP 环境的扩展目录下(例如 e:\app\ext)。
  2. 配置 php.ini:打开 php.ini 文件,在扩展部分添加一行:
extension=foo.dll
  1. 重启服务:重启 Apache/IIS 或 php-fpm 进程。
  2. 验证:访问 phpinfo() 页面。如果在列表中找到 foo 扩展及其版本信息,说明扩展已成功加载。您现在可以在 PHP 代码中直接使用 foo() 函数了。

常见问题排查

  • L1081 Error**: 如果链接出现 L1081 错误,通常是.lib 文件路径错误或版本号不匹配。请确保拷贝的是与 PHP 版本完全一致的 php5ts.lib。
  • Undefined symbols**: 若提示 Zend API 未定义,请检查 VC++ 附加包含目录是否正确指向了 PHP 源码根目录。
  • 编码问题**: PHP 源码中的 C 文件通常使用 UTF-8 without BOM 编码。若在中文 Windows 上使用记事本编辑,请确保另存为 UTF-8 格式,以免引入乱码字符导致编译失败。

以上就是 Windows 下开发并编译 PHP 扩展的详细操作过程。通过规范的工程配置和骨架脚本,开发者可以高效地构建自定义功能模块。更多关于 PHP 底层开发和扩展优化的技术文章,请关注本站其他相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。