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开一个工程,对于开发调试还是很有帮助的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,132评论 25 707
  • PHP安装redis扩展 以下操作需要在下载的 phpredis 目录中完成: 如果你是 PHP7 版本,则需要下...
    手表大大阅读 1,459评论 0 1
  • 0.前言 在之前一段时间涉及PHP扩展开发,对PHP源代码有调试需求,然而网上大部分都是在LINUX下调试的教程,...
    lambdacalculus阅读 4,413评论 1 5
  • 当行李箱放上托运带,当登机牌拿在手上,当空乘站在机门欢迎你的时候,扣紧安全带,飞机在跑道上加速,直到飞上云霄,嗡嗡...
    黄木卜阅读 1,144评论 4 8
  • 鉴于近日群里有一些小伙伴对于flex布局不是很清楚,我决定总结flex的相关知识点,希望能加深大家的印象,同时也是...
    宋大肿阅读 6,008评论 5 9