寫(xiě)在前頭
這個(gè)配置是基于windows的IIS部署php的情況下饭入,開(kāi)發(fā)php的擴(kuò)展,編譯出dll文件,供應(yīng)php中代碼可用function五芝。
通過(guò)2天在baidu來(lái)回折騰,終于自己摸索出了工作方案辕万,記錄備忘枢步,也可以被其他程序員參考 沉删。
baidu上的內(nèi)容,實(shí)在太模糊了醉途,寫(xiě)到重點(diǎn)都沒(méi)有矾瑰。
關(guān)鍵要素
- 服務(wù)器OS:windows,開(kāi)發(fā)機(jī)是windows10
- http服務(wù):IIS
- php版本:VC14編譯php7.1.*隘擎,x64殴穴,nts
- vs2015的開(kāi)發(fā)IDE
環(huán)境是什么,決定了用什么方式進(jìn)行開(kāi)發(fā)货葬,所以必須要想明白自己的環(huán)境狀態(tài)推正。因?yàn)榫幾g的擴(kuò)展需要和編譯的php主程序匹配,否則擴(kuò)展是不能使用的宝惰。
要素 | 值 | 說(shuō)明 |
---|---|---|
php版本 | 7.1.7 | 從微軟的iis express上下載的植榕,參考微軟的start sql server by php on windows |
編譯器 | VC14 | 使用vs2015 c++編譯器 |
線程安全 | no | 非線程安全,匹配IIS上fast cgi的php版本都是NTS的編譯的php |
編譯環(huán)境 | X64 | 在64位環(huán)境中編譯的可執(zhí)行程序 |
環(huán)境準(zhǔn)備
安裝cygwin
下載地址:https://cygwin.com/install.html;
可以考慮在安裝之后加載bison尼夺,因?yàn)閜hp的編譯過(guò)程可以使用尊残。不安裝也可以,php上下載的編譯工具中自帶淤堵。
安裝vs2015 c++的開(kāi)發(fā)IDE
實(shí)際不需要IDE寝衫,但是考慮到微軟的東西,還是打包下載的比較保險(xiǎn)拐邪。
vs2015中必須有C++的編譯器即可慰毅。其他都不用。
我測(cè)試使用vs2017扎阶,但是編譯后出問(wèn)題汹胃,還是倒回vs2015,編譯后可以使用东臀。
部署php的sdk
下載地址:http://windows.php.net/downloads/php-sdk/
我使用了:deps-7.1-vc14-x64着饥,php編譯的依賴包。
還需要使用:php-sdk-binary-tools-20110915惰赋,注意是老版本了宰掉,沒(méi)有具體的新版本,實(shí)際也可以用赁濒。
部署php的源代碼
下載地址:http://windows.php.net/downloads/releases/
我使用了:php-7.1.2-src轨奄,雖然運(yùn)行的php是7.1.7,但是實(shí)際測(cè)試拒炎,源碼的版本只要小版本一致即可挪拟。根據(jù)php.net的說(shuō)法,使用高版本的php源碼是沒(méi)有問(wèn)題的枝冀。還沒(méi)有時(shí)間做測(cè)試舞丛。
維護(hù)工作目錄
- 解壓php-sdk-binary-tools-20110915耘子,形成一個(gè)tools目錄
- 解壓php源碼果漾,形成php7.1src目錄
- 自建dev目錄球切,屆時(shí)可以存放擴(kuò)展的代碼
配置OS的PATH
- 配置php的運(yùn)行目錄,這樣可以cmd中執(zhí)行php.exe
- 配置tools目錄
- 配置源碼目錄绒障,因?yàn)榫幾g過(guò)程需要使用源碼內(nèi)的一些bat
工作步驟
復(fù)制必要的文件到工作目錄
- 使用VS2015的cmd工具
我的運(yùn)行環(huán)境是php的x64nts吨凑,因此選擇x64的cmd工具。在cmd中進(jìn)入tools目錄(解壓php-sdk-binary-tools-20110915) - 執(zhí)行tools的環(huán)境預(yù)設(shè)
cd bin
phpsdk_setvars.bat
phpsdk_buildtree.bat extdev
extdev是一個(gè)工作目錄户辱,這個(gè)可以自己定義鸵钝,我這里就用這個(gè)。執(zhí)行后庐镐,會(huì)在tools的并排目錄里創(chuàng)建好extdev目錄恩商,內(nèi)含多個(gè)vc**的目錄。
由于工具是2011年的必逆,因此沒(méi)有VC14怠堪,需要自己維護(hù)一個(gè)VC14,再創(chuàng)建一個(gè)x64目錄名眉。雖然應(yīng)該也配套建設(shè)x86粟矿,但是我的運(yùn)行php的x64的,因此x86就不必了损拢。
另外extdev的目錄工具只是產(chǎn)生一套規(guī)范目錄陌粹,與開(kāi)發(fā)其實(shí)沒(méi)有硬關(guān)系「Q梗可以cd..后做掏秩,也可以不用做。
創(chuàng)建deps環(huán)境
將deps-7.1-vc14-x64的壓縮包內(nèi)容荆姆,添加到x64下哗讥。
實(shí)際操作感覺(jué),也無(wú)所謂工作目錄那么嚴(yán)謹(jǐn)也一樣可以編譯php擴(kuò)展胞枕。但是嚴(yán)謹(jǐn)?shù)墓ぷ髂夸浭莻€(gè)好習(xí)慣杆煞。復(fù)制源碼
將源碼包解壓到x64中,形成php714-src的目錄腐泻。
最終形成了我的工作環(huán)境目錄:
D:
| -- work
| -- php_sdk_tool // 解壓php-sdk-binary-tools-20110915
| -- extdev // 運(yùn)行phpsdk_buildtree.bat extdev之后得到
| -- vc14 // 自建
| -- x64 // 自建
| -- deps // 解壓deps-7.1-vc14-x64
| -- php714-src // 解壓php714的源碼决乎,編譯需要的configure.js等都在這里,這個(gè)是執(zhí)行編譯命令的目錄
| -- ext // php標(biāo)準(zhǔn)擴(kuò)展目錄
| -- myext // 執(zhí)行php ext_skel_win32.php --extname=myext之后php創(chuàng)建派桩,自開(kāi)發(fā)擴(kuò)展源碼就在這里构诚,.32配置文件在這里
| -- x64 // 64位編譯結(jié)果輸出
| -- Release // 編譯非線程安全的輸出,這里可以找到編譯結(jié)果php_myext.dll铆惑,如果編譯發(fā)生LKN范嘱,php7.lib復(fù)制到這里重新編譯
| -- Release_TS // 編譯線程安全的輸出送膳,結(jié)果dll在這里
| -- Release // 32位擴(kuò)展的編譯輸出,應(yīng)該是非線程安全丑蛤,我沒(méi)有測(cè)試過(guò)叠聋,邏輯推測(cè)
生成程序模板
到php714-src中,cd到ext目錄受裹,找到對(duì)應(yīng)的win32的開(kāi)發(fā)配置php程序碌补,修改cygwin的bin路徑。(在windows開(kāi)發(fā)就是這樣麻煩棉饶,linux中應(yīng)該不用吧厦章?)
cd..
cd php714-src
cd ext
vim ext_skel_win32.php
//$cygwin_path設(shè)置為你當(dāng)前cygwin安裝目錄的bin目錄。
php ext_skel_win32.php --extname=%your extension name% // eg : myext
這個(gè)操作完成后照藻,會(huì)在ext的目錄下袜啃,出現(xiàn)%your extension name% (myext)的文件夾。就是php工具創(chuàng)建的擴(kuò)展空模板幸缕。修改代碼群发,再編譯,就可以完成擴(kuò)展的開(kāi)發(fā)冀值。
cd %your extension name% // eg : myext
進(jìn)入自己的擴(kuò)展目錄也物,其中有2個(gè)配置文件需要修改(參考php ext_skel_win32.php 執(zhí)行后的說(shuō)明也可以明白)。
一個(gè)是linux系統(tǒng)中需要的*.m4的配置列疗,一個(gè)是windows系統(tǒng)的.w32文件配置滑蚯。
我們這里修改.w32的文件。將一下被注釋的代碼復(fù)原:
ARG_ENABLE("myext", "enable myext support", "no");
編譯程序配置
然后回到源碼目錄抵栈,執(zhí)行配置程序的創(chuàng)建工作告材。
cd..
buildconf --force
configure --help
通常操作第一步后,如果成功古劲,會(huì)提示你操作第二步斥赋。
這個(gè)時(shí)候,系統(tǒng)會(huì)提示有configure.js的某行代碼出錯(cuò)产艾,直接vim去修改這行代碼疤剑,一般是末尾的注釋需要修正:
ARG_ENABLE("myext", "enable myext support", "no"); */ -- 就是這個(gè)地方
然后再次執(zhí)行configure --help∶票ぃ可以查看配置的功能清單隘膘。重點(diǎn)關(guān)注自己的myext是否存在,還有諸如zts功能(線程安全與否的開(kāi)關(guān))杠览。
執(zhí)行擴(kuò)展編譯
在cmd中繼續(xù)執(zhí)行命令
configure --disable-all --enable-cli --disable-zts --enable-myext=shared
// ^ 關(guān)閉其他功能 ^ 編譯非線程安全
nmake
如果要編譯線程安全的弯菊,則不需要--disable-zts
根據(jù)提示應(yīng)該繼續(xù)執(zhí)行nmake。
期間可能會(huì)出現(xiàn)若干錯(cuò)誤踱阿,一般都是環(huán)境配置的問(wèn)題:
- 使用vs2015 x64的命令行可以減少諸如cl.exe管钳、link.exe的問(wèn)題
- 編譯器報(bào)告lnk的問(wèn)題钦铁,基本都是php7.lib的文件不到位的問(wèn)題〔牌幔可以從php的運(yùn)行系統(tǒng)中牛曹,在php的目錄dev中找到這個(gè)文件,復(fù)制到編譯工作目錄:php714\src\x64\release\
- 正常情況下栽烂,編譯完成后躏仇,會(huì)在源碼目錄中出現(xiàn)對(duì)應(yīng)的輸出目錄:release(對(duì)應(yīng)x86的編譯)和x64(對(duì)應(yīng)x64的編譯)恋脚。而x64又出現(xiàn)Release_TS和Release目錄腺办,分別對(duì)應(yīng)線程安全和非線程安全。
測(cè)試使用
將編譯后的輸出糟描,本次是php714\src\x64\release\中的php_myext.dll復(fù)制到php的運(yùn)行環(huán)境怀喉,并配置ini。
在cmd中執(zhí)行php代碼船响,就可以查看到extension是否成功加載躬拢。如果加載有問(wèn)題,會(huì)馬上有警告见间。
- 警告模塊不是擴(kuò)展模塊:可能編譯器不正確聊闯,比如php714使用VC14,而編譯擴(kuò)展使用了不匹配的
- 警告不是有效的win32米诉,則運(yùn)行php的位數(shù)和擴(kuò)展編譯的位數(shù)不匹配菱蔬,即運(yùn)行php的版本和擴(kuò)展編譯的版本應(yīng)該都是對(duì)應(yīng)x86或x64
- 警告找不到模塊:可能是運(yùn)行的php的線程安全與編譯的線程安全開(kāi)關(guān)不匹配。
測(cè)試方式:
php -r "phpinfo();"
php -r "echo confirm_myext_compiled(0);"
為了方便查看史侣,在phpinfo制作一個(gè)php文件通過(guò)http訪問(wèn)也可以看到擴(kuò)展myext的加載拴泌。
注意事項(xiàng)
從baidu上其他的使用vs2015引入擴(kuò)展目錄創(chuàng)建工程,我沒(méi)有操作成功惊橱。多半都是編譯環(huán)境的問(wèn)題蚪腐,我發(fā)現(xiàn)百度的內(nèi)容基本都是php5的,php7很少税朴。估計(jì)php7升級(jí)到這個(gè)版本后回季,擴(kuò)展的開(kāi)發(fā)有了變化,因此我怎么也沒(méi)有成功正林。(實(shí)際是成功編譯了dll泡一,但是php不認(rèn)這個(gè)dll)。不過(guò)使用vs2015開(kāi)一個(gè)工程卓囚,對(duì)于開(kāi)發(fā)調(diào)試還是很有幫助的瘾杭。