Windows 下 PHP 扩展开发
Windows 下 PHP 扩展开发
开源中国董事会主席 发表于4年前
Windows 下 PHP 扩展开发
  • 发表于 4年前
  • 阅读 717
  • 收藏 6
  • 点赞 1
  • 评论 4

腾讯云 新注册用户 域名抢购1元起>>>   

一、环境配置:

1、下载安装 Eclipse (我安装的是 Indigo 版本,下载地址:http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/indigosr1);
2、下载安装JDK,并配置环境变量(否则没法使用 Eclipse);
3、下载安装 Cygwin(目录路径最好不要有空格和中文,假设安装路径为:D:\Software\Cygwin);
4、下载安装MinGW(需要用到其中的 C 语言标准库,需要目录路径不要有空格和中文,否则会安装不成功,假设安装路径为:D:\Software\MinGW),配置环境变量:

  • MINGW_HOME:D:\Software\MinGW

  • C_INCLUDE_PATH:%MINGW_HOME%\include

  • Path中添加:%MINGW_HOME%\bin

5、下载安装Visual Studio(不需要完整安装,但是 C/C++组件必须要装,我安装的是 Visual Studio 2010 版);
6、下载或直接安装 Eclipse 的 C/C++ 插件CDT(我安装的是8.0.1版本的,8.1的安装不上)
7、下载 win32 编译工具:http://www.php.net/extra/win32build.zip
8、下载  PHP 使用的 DNS 解析器的源代码:http://www.php.net/extra/bindlib_w32.zip
9、将  win32build.zip 和 bindlib_w32.zip 解压到一个目录下,比如:D:\Software\ win32build

二、创建项目

1、 在 Eclipse 中新建 ”C Project“,”Project Type“ 选择 ”Executable“ 或者 ”Makefile Project“下的 ”Empty Project“,然后再右侧展开的 ”Toolchains” 选择 “MinGW GCC”,假设项目路径为:E:\Extension\demo;
2、将下载的PHP(我的版本为5.3.8)源代码放到项目目录中,PHP源码路径为:E:\Extension\demo\php-5.3.8,下面简称为: PHPROOT;
3、修改 PHPROOT/ext/ext_skel_win32.php 中变量 “$cygwin_path” 为 Cygwin 的 bin 路径,即为上面的 D:\Software\Cygwin\bin;
4、在命令行中进入目录 PHPROOT/ext;
5、假设电脑上有安装好了的 PHP,路径为:D:\Software\PHP,在命令中进入目录 PHPROOT/ext 后,执行命令:D:\Software\PHP\php.exe ext_skel_win32.php --extname=extname,会在 PHPROOT/ext 下生成目录 extname;

三、扩展开发

四、编译扩展

1、将安装好了的 PHP 目录下的 dev 目录中的 php5ts.lib (此处路径为:D:\Software\PHP\dev\php5ts.lib)拷贝到你新建的扩展目录下;
2、使用 Visual Studio 打开 PHPROOT/ext/extname 目录下的 extname.dsp;
3、“项目”右键->属性

  • 属性 -> 配置属性 -> 常规:"MFC的使用"选择“在共享 DLL 中使用 MFC”

  • 属性 -> 配置属性 -> C/C++ -> 预处理器:将 "LIBZEND_EXPORTS" 去掉,否则会把包含的PHP头文件中的ZEND_API就会被申明为 __declspec(dllexport), 导致无法在链接的时候无法解析符号

4、使用 Visual Studio 命令提示 (工具->Visual Studio 命令提示)执行以下命令:

  • 进入 PHP 源代码目录:cd PHPROOT

  • 执行 buildconf.bat:buildconf.bat

  • 设置临时环境变量:set path=%path%;D:\Software\win32build\bin

  • 将 config.w32 文件中的 ARG_WITH 和 ARG_ENABLE 前的注释去掉

  • cscript /nologo configure.js --with-php-build="../win32build" --without-libxml  --disable-odbc(如果想要No Thread Safe 模式就在上面的命令最后加上参数 --disable-zts)

  • 看看 PHPROOT/main 目录下是否生成了 config.w32.h 这个文件

  • 在 Visual Studio 项目 右键 生成

5、使用第三方库,以 libxml2 为例

  • 下载开发包:libxml2 的最新包下载地址为: http://xmlsoft.org/sources/win32/libxml2-2.7.8.win32.zip、iconv(libxml 字符串编码转换需要用到) 的罪行开发包为:http://xmlsoft.org/sources/win32/iconv-1.9.2.win32.zip

  • 解压,假设 libxml2 解压后的地址为:D:\source\libxml2,iconv 解压后的地址为:D:\source\iconv

  • 将 D:\source\libxml2\lib\libxml2.lib 和 D:\source\iconv\lib\iconv.lib 拷贝到 PHPROOT/ext/extname 下

  • 属性 -> 配置属性 -> 链接器 -> 输入 -> 附加依赖项:中加上 libxml2.lib 和 iconv.lib

  • 属性 -> 配置属性 -> VC++ 目录 -> 可执行文件目录:中加上 D:\source\libxml2\bin 和 D:\source\iconv\bin

  • 属性 -> 配置属性 -> VC++ 目录 -> 包含目录:中加上 D:\source\libxml2\include 和 D:\source\iconv\include 这里面有所需要用到的头文件

  • 属性 -> 配置属性 -> VC++ 目录 -> 库目录:中加上 D:\source\libxml2\lib 和 D:\source\iconv\lib 这里面是所需的库库文件

  • 配置 -> 配置属性 -> C/C++ -> 常规 -> 附加包含目录: 目录路径中的 “phpx” 更改为 PHPROOT 的目录名 否则,在编译时,找不到所需的头文件

      【可能遇到的错误】

  1. stat.inl(44) : error C2466: 不能分配常量大小为 0 的数组

          utime.inl(44) : error C2466: 不能分配常量大小为 0 的数组

        打开 <Visual Studio 目录>\vc\include\malloc.h,找到

#define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr) ]

          更改为:

#ifdef PHP_WIN32  
#define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr)?(expr):1 ]  
#else  
#define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr) ]  
#endif

     2、根据 PHP 的版本修改 PHPROOT/main/config.w32.h 中 #define PHP_COMPILER_ID 的值为 “VC6” 或 “VC9”,否则无法加载模块

     3、如果两个或以上目录中存在多个同名文件,如:request/exception.h、request/exception.c和response/exception.h、response/exception.c,在编译时会遇到以下错误:

warning LNK4042: 对象被多次指定;已忽略多余的指定

         纠正办法:属性 -> 配置属性 -> C/C++ -> 输出文件 -> 对象文件名 的值改为: .\Release_TS\%(RelativeDir)


五、高版本 Visual Studio 编译所需低版本 php 动态库的妙招

如我使用 Visual Studio 2012 编译 VC9 版本的 PHP 动态库

在执行 buildconf.bat 后,打开 PHPROOT/configure.js 找到

var VC_VERSIONS = new Array();

添加

VC_VERSIONS[1700] = 'MSVC12 (Visual C++ 2012)';

var VC_VERSIONS_SHORT = new Array();

添加

VC_VERSIONS_SHORT[1700] = 'VC12';

否则,执行 cscript /nologo configure.js 时要报错。

最后,打开 PHPROOT/main/config.w32.h,找到

#define COMPILER "MSVC12 (Visual C++ 2012)"
#define PHP_COMPILER_ID "VC12"

修改为

#define COMPILER "MSVC9 (Visual C++ 2009)"
#define PHP_COMPILER_ID "VC9"
标签: PHP
共有 人打赏支持
开源中国董事会主席
粉丝 109
博文 20
码字总数 14304
作品 2
评论 (4)
ddatsh
各种折腾,还是VS爽
铂金小狼
来支持一下勇哥
开源中国董事会主席

引用来自“铂金小狼”的评论

来支持一下勇哥

来 嘣一口,最后又增加了点儿
铂金小狼
打死通用
×
开源中国董事会主席
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: