2018-02-02 配置Windows下开发PHP扩展

写在前头

这个配置是基于windows的IIS部署php的情况下,开发php的扩展,编译出dll文件,供应php中代码可用function。
通过2天在baidu来回折腾,终于自己摸索出了工作方案,记录备忘,也可以被其他程序员参考 。
baidu上的内容,实在太模糊了,写到重点都没有。

关键要素

  • 服务器OS:windows,开发机是windows10
  • http服务:IIS
  • php版本:VC14编译php7.1.*,x64,nts
  • vs2015的开发IDE

环境是什么,决定了用什么方式进行开发,所以必须要想明白自己的环境状态。因为编译的扩展需要和编译的php主程序匹配,否则扩展是不能使用的。

要素 说明
php版本 7.1.7 从微软的iis express上下载的,参考微软的start sql server by php on windows
编译器 VC14 使用vs2015 c++编译器
线程安全 no 非线程安全,匹配IIS上fast cgi的php版本都是NTS的编译的php
编译环境 X64 在64位环境中编译的可执行程序

环境准备

安装cygwin

下载地址:https://cygwin.com/install.html;
可以考虑在安装之后加载bison,因为php的编译过程可以使用。不安装也可以,php上下载的编译工具中自带。

安装vs2015 c++的开发IDE

实际不需要IDE,但是考虑到微软的东西,还是打包下载的比较保险。
vs2015中必须有C++的编译器即可。其他都不用。
我测试使用vs2017,但是编译后出问题,还是倒回vs2015,编译后可以使用。

部署php的sdk

下载地址:http://windows.php.net/downloads/php-sdk/
我使用了:deps-7.1-vc14-x64,php编译的依赖包。
还需要使用:php-sdk-binary-tools-20110915,注意是老版本了,没有具体的新版本,实际也可以用。

部署php的源代码

下载地址:http://windows.php.net/downloads/releases/
我使用了:php-7.1.2-src,虽然运行的php是7.1.7,但是实际测试,源码的版本只要小版本一致即可。根据php.net的说法,使用高版本的php源码是没有问题的。还没有时间做测试。

维护工作目录

  1. 解压php-sdk-binary-tools-20110915,形成一个tools目录
  2. 解压php源码,形成php7.1src目录
  3. 自建dev目录,届时可以存放扩展的代码

配置OS的PATH

  1. 配置php的运行目录,这样可以cmd中执行php.exe
  2. 配置tools目录
  3. 配置源码目录,因为编译过程需要使用源码内的一些bat

工作步骤

复制必要的文件到工作目录

  1. 使用VS2015的cmd工具
    我的运行环境是php的x64nts,因此选择x64的cmd工具。在cmd中进入tools目录(解压php-sdk-binary-tools-20110915)
  2. 执行tools的环境预设
cd bin
phpsdk_setvars.bat
phpsdk_buildtree.bat extdev

extdev是一个工作目录,这个可以自己定义,我这里就用这个。执行后,会在tools的并排目录里创建好extdev目录,内含多个vc**的目录。
由于工具是2011年的,因此没有VC14,需要自己维护一个VC14,再创建一个x64目录。虽然应该也配套建设x86,但是我的运行php的x64的,因此x86就不必了。
另外extdev的目录工具只是产生一套规范目录,与开发其实没有硬关系。可以cd..后做,也可以不用做。

  1. 创建deps环境
    将deps-7.1-vc14-x64的压缩包内容,添加到x64下。
    实际操作感觉,也无所谓工作目录那么严谨也一样可以编译php扩展。但是严谨的工作目录是个好习惯。

  2. 复制源码
    将源码包解压到x64中,形成php714-src的目录。

最终形成了我的工作环境目录:

D:
 | -- work
       | -- php_sdk_tool                     // 解压php-sdk-binary-tools-20110915
       | -- extdev                           // 运行phpsdk_buildtree.bat extdev之后得到 
              | -- vc14                      // 自建
                     | -- x64                // 自建 
                            | -- deps        // 解压deps-7.1-vc14-x64
                            | -- php714-src  // 解压php714的源码,编译需要的configure.js等都在这里,这个是执行编译命令的目录
                                   | -- ext  // php标准扩展目录
                                         | -- myext // 执行php ext_skel_win32.php --extname=myext之后php创建,自开发扩展源码就在这里,.32配置文件在这里
                                   | -- x64  // 64位编译结果输出
                                          | -- Release // 编译非线程安全的输出,这里可以找到编译结果php_myext.dll,如果编译发生LKN,php7.lib复制到这里重新编译
                                          | -- Release_TS // 编译线程安全的输出,结果dll在这里
                                   | -- Release // 32位扩展的编译输出,应该是非线程安全,我没有测试过,逻辑推测

生成程序模板

到php714-src中,cd到ext目录,找到对应的win32的开发配置php程序,修改cygwin的bin路径。(在windows开发就是这样麻烦,linux中应该不用吧?)

cd..
cd php714-src
cd ext
vim ext_skel_win32.php
//$cygwin_path设置为你当前cygwin安装目录的bin目录。
php ext_skel_win32.php --extname=%your extension name% // eg : myext

这个操作完成后,会在ext的目录下,出现%your extension name% (myext)的文件夹。就是php工具创建的扩展空模板。修改代码,再编译,就可以完成扩展的开发。

cd %your extension name% // eg : myext

进入自己的扩展目录,其中有2个配置文件需要修改(参考php ext_skel_win32.php 执行后的说明也可以明白)。
一个是linux系统中需要的*.m4的配置,一个是windows系统的.w32文件配置。
我们这里修改.w32的文件。将一下被注释的代码复原:

ARG_ENABLE("myext", "enable myext support", "no");

编译程序配置

然后回到源码目录,执行配置程序的创建工作。

cd..
buildconf --force
configure --help

通常操作第一步后,如果成功,会提示你操作第二步。
这个时候,系统会提示有configure.js的某行代码出错,直接vim去修改这行代码,一般是末尾的注释需要修正:

ARG_ENABLE("myext", "enable myext support", "no"); */ -- 就是这个地方

然后再次执行configure --help。可以查看配置的功能清单。重点关注自己的myext是否存在,还有诸如zts功能(线程安全与否的开关)。

执行扩展编译

在cmd中继续执行命令

configure --disable-all --enable-cli --disable-zts --enable-myext=shared
//                ^ 关闭其他功能                 ^ 编译非线程安全
nmake

如果要编译线程安全的,则不需要--disable-zts
根据提示应该继续执行nmake。

期间可能会出现若干错误,一般都是环境配置的问题:

  1. 使用vs2015 x64的命令行可以减少诸如cl.exe、link.exe的问题
  2. 编译器报告lnk的问题,基本都是php7.lib的文件不到位的问题。可以从php的运行系统中,在php的目录dev中找到这个文件,复制到编译工作目录:php714\src\x64\release\
  3. 正常情况下,编译完成后,会在源码目录中出现对应的输出目录:release(对应x86的编译)和x64(对应x64的编译)。而x64又出现Release_TS和Release目录,分别对应线程安全和非线程安全。

测试使用

将编译后的输出,本次是php714\src\x64\release\中的php_myext.dll复制到php的运行环境,并配置ini。
在cmd中执行php代码,就可以查看到extension是否成功加载。如果加载有问题,会马上有警告。

  1. 警告模块不是扩展模块:可能编译器不正确,比如php714使用VC14,而编译扩展使用了不匹配的
  2. 警告不是有效的win32,则运行php的位数和扩展编译的位数不匹配,即运行php的版本和扩展编译的版本应该都是对应x86或x64
  3. 警告找不到模块:可能是运行的php的线程安全与编译的线程安全开关不匹配。

测试方式:

php -r "phpinfo();"
php -r "echo confirm_myext_compiled(0);"

为了方便查看,在phpinfo制作一个php文件通过http访问也可以看到扩展myext的加载。

注意事项

从baidu上其他的使用vs2015引入扩展目录创建工程,我没有操作成功。多半都是编译环境的问题,我发现百度的内容基本都是php5的,php7很少。估计php7升级到这个版本后,扩展的开发有了变化,因此我怎么也没有成功。(实际是成功编译了dll,但是php不认这个dll)。不过使用vs2015开一个工程,对于开发调试还是很有帮助的。

你可能感兴趣的:(2018-02-02 配置Windows下开发PHP扩展)