php官方提供扩展编译成 window 的 dll 的官方文档,
Visual C++ 14.0 (Visual Studio 2015) for PHP 7.0 or PHP 7.1.
Visual C++ 15.0 (Visual Studio 2017) for PHP 7.2 or PHP 7.3.
Visual C++ 16.0 (Visual Studio 2019) for PHP 7.4.
在官方文档中说到的环境要求,Visual Studio 环境可以直接用 Visual Studio ide 进行安装,
不是指Visual C++ ,所以运行 phpsdk-vc15-x64
会出现 Could not deternine 'vc15' directory
的错误,
php 编译成 dll 的环境可以使用这个 ide 进行安装
到官网下载 Visual Studio Install
在 Visual Studio Professional 2017
下选择修改后,选在对应的环境安装
这样需要的环境就已经准备好了
php-sdk-binary-tools 是有官方提供的工具,
1. 下载 php-sdk-binary-tools
git clone https://github.com/Microsoft/php-sdk-binary-tools cd php-sdk-binary-tools
下载需要编译拓展的对应php版本的源码
https://windows.php.net/download/
2. 调用启动脚本,例如我这里是 php7.2,对应 Visual Studio 2017 64 位版本,调用 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 目录。
vc##
是您正在使用的编译器版本(eq vc15)
x##
是你的构建的系统位数(x86 或 x64)
例如我这里是: F:\www\php-sdk-binary-tools\phpdev\vc15\x64\php-7.2.12-src
5. 进入解压的 php 源码目录,运行 phpsdk_deps -u
或 phpsdk_deps --update --branch master
,php 会自动下载 需要的依赖包 (php7 以前需要手动下载 php-dsp 文件)(php7+本步骤可省略,5.6未测试)
上面已经将编译前的构建准备环境好了,编译前在 php-sdk-binary-tools 中调用 starter 脚本以自动设置所需构建配置的环境 phpsdk-vc15-x64.bat
,
切换到 php源码根目录
,然后执行 buildconf
命令。
如果提示输入错误: 没有文件扩展“.js”的脚本引擎。
这里主要原因是:系统安装 IDE(Dreamwear、UltraEdit、EditPlus,我之前安装 phpstorm 修改了)后后修改了.js 文件的默认打开方式。
当想直接执行 js 脚本时就会出现此错误。
快捷键 win + r
,然后输入 regedit
, 打开注册表编辑器,定位 [HKEY_CLASSES_ROOT.js] 这一项,双击默认值将其改为 “JSFile” 即可。如图所示:
然后就可以执行成功了
执行以下命令进行编译 php 配置:
configure --disable-all --enable-cli
注意:可以自己适当调整,参数可以使用 configure --help
查看,如
configure --disable-all --enable-cli --enable-debug --with-all-shared
执行成功后会提示执行 nmake
执行这一步会在 main
目录下生成 config.w32.h
文件,编译 php扩展
会需要用到这个文件,
所以如果是编译 php 扩展则执行下一步 nmake
,如果是只是 php 编译扩展可以不执行 `nmake
然后执行 nmake
开始编译
等待数分钟后,在 php-src 目录应该够找到能够多了一个编译位数的目录
(x32 或 x64),在目录下有 Release_TS (或者 Release_NTS 或者 Debug_TS ) 这样的目录
如果编译正常的话 这下面会有 php.exe 文件 证明编译 php 文件成功.
运行编译好的 php.exe -v
查看是否正常运行
如果我们只是编译某些已经开放好的扩展源码,可以不用运行这一步,这里创建一个 demo 扩展进行编译。
使用 git bash
进入到源码的地址\ext
目录,执行:
php.exe ext_skel_win32.php --extname=my_function
注:这里为什么要使用 git bash 工具,是因为 git bash 自带模拟 linux 环境,my_function
为我这里需要创建的扩展,具体可以根据自己更改
执行工具创建时不是提示'sh' is not recognized as an internal or external command,
可以看到在源码 ext 目录下多了一个 my_function
的目录,这个就是我们刚刚使用使用 ext_skel_win32.php
命令出创建的初始扩展代码
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
前:
切换回 window 的 cmd
1. 进入 php-sdk-binary-tools
目录使用 phpsdk-vc15-x64.bat
2. 切换到 php 源码目录,运行 buildconf
3. 在执行完 buildconf
后如果执行 configure
命令,会提示类似以下错误:(字符)
打开提示的文件,找到对应的行数,发现结尾多出多余的注释符号。这里可能是工具的问题,
解决方法:打开扩展源码的 config.w32
,找到 // Otherwise, use ARG_ENABLE
这句注释删除,重新运行 buildconf
就可以了。(此方法不友好,不如直接按照上图删掉最后的*/,省事)
注意:
删除的注释是你需要编译参数的上面的注释,这里看 ARG_WITH
还是 ARG_ENABLE
,只要删除对应上面的注释即可
ARG_WITH
和 ARG_ENABLE
不可同时开启
运行 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
-> 运行编译配置命令
,可以看到编译配置成功提示 Enable extensions:
多出我们的扩展:
5. 运行 nmake
命令进行编译,等待几分钟到十几分钟后,终端如果出现类似下面编译成功自己即表示编译成功
并且在源码目录下发现多了一个 x64
的目录,如果编译的事 32 位则是 x86
,
里面有一个 Release_TS
(release 表示非 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 = "./"
7. 测试
添加一个测试文件 test.php
<?phpmy_function_test();
然后运行编译生成的php目录\php.exe test.php
到这里 window 下编译 php 和编译 php 扩展就已经成功了。