文档章节

Windows 下 PHP 扩展开发

开源中国董事会主席
 开源中国董事会主席
发布于 2013/10/11 13:47
字数 1305
阅读 726
收藏 6
PHP

一、环境配置:

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"

© 著作权归作者所有

共有 人打赏支持
开源中国董事会主席

开源中国董事会主席

粉丝 111
博文 20
码字总数 14304
作品 2
成都
高级程序员
加载中

评论(4)

铂金小狼
铂金小狼
打死通用
开源中国董事会主席
开源中国董事会主席

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

来支持一下勇哥

来 嘣一口,最后又增加了点儿
铂金小狼
铂金小狼
来支持一下勇哥
ddatsh
ddatsh
各种折腾,还是VS爽
PHP调试工具--TestPHP

在Windows下开发PHP过程中,有的时候需要编写调试一段代码,Windows下又无法使用php -a PHP新版的内置服务器打开调试编写起来又太麻烦,所以开发TestPHP TestPHP不进行是新人学习PHP的必备工...

BuFuZao
2013/08/29
1K
3
PHP的开源扩展--WinBinder

WinBinder是一个PHP的开源扩展,它可让PHP程序员轻松的构建原生Windows应用程序。 WinBinder的特点 它封装了大部分的Windows API,使PHP在Windows下开发从而变得很容易。 让你像使用VB一样,...

匿名
2013/01/14
1K
0
windows下开发并编译PHP扩展(步骤说明)

开发PHP扩展对于普通程序员来讲可能一直是一件很神秘的工作,其实,只要你对C语言熟悉,了解了开发PHP扩展的步骤和规则,开发PHP扩展也是一件很普通的工作。 现在就简单说一在WINDOWS下开发P...

mac_zhao
2011/04/19
0
0
UPUPW 发布 PHP 7.0 Redis 扩展 dll

PHP 7.0.0 正式版发布有一段时间了,但是与之对应的扩展组件非常之少,特别是windows上用PHP7搭建开发平台,组件太少肯定是影响开发的。 目前PHP官网的PECL上日常用到的大部分PHP扩展组件都没...

UPUPW
2015/12/16
5.2K
5
**小草**/taskPHP

当前版本 2.0 历史版本 -->taskPHP1.0 taskPHP taskPHP基于php开发的定时计划任务框架,利用多进程实现任务的分配和运行,多种进程间通信驱动支持,支持多线程模式需要安装pthreads扩展(可选),支...

**小草**
2017/04/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

@SpringBootApplication 注解

@SpringBootApplication注解是一个组合注解,包含以下注解 @Target(ElementType.TYPE) 注解的作用目标 @Retention(RetentionPolicy.RUNTIME) Reteniton的作用是定义被它所注解的注解保留多久,...

java.刘
37分钟前
0
0
sentinel自定义DataSource实战

序 本文主要研究一下如何自定义sentinel的DataSource,这里以jdbc为例。 maven <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sen......

go4it
53分钟前
1
0
xgboost/gbdt在调参时为什么树的深度很少就能达到很高的精度?

问题: 用xgboost/gbdt在在调参的时候把树的最大深度调成6就有很高的精度了。但是用DecisionTree/RandomForest的时候需要把树的深度调到15或更高。用RandomForest所需要的树的深度和Decisio...

tantexian
54分钟前
0
0
php-fpm的pool - 慢执行日志 - 进程管理 - open_basedir

php-fpm的pool : 为避免多站点使用同一个pool时因一个站点故障导致php资源耗尽,牵连使用同一个pool的其他站点的正常工作,可对每一个站点设置独立pool。 增加pool: 1.编辑php-fpm配置文件...

ZHENG-JY
今天
0
0
Linux之ssh服务默认端口修改

导读 SSH是标准的网络协议,可用于大多数UNIX操作系统,能够实现字符界面的远程登录管理,它默认使用22号端口,采用密文的形式在网络中传输数据,相对于通过明文传输的Telnet,具有更高的安全...

问题终结者
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部