小編給大家分享一下編譯PHP擴(kuò)展的方法是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
你已經(jīng)知道如何去編譯PHP本身,下一步我們將編譯外部擴(kuò)展。我們將討論擴(kuò)展的構(gòu)建過(guò)程和可用的編譯選項(xiàng)。
在前一個(gè)章節(jié)你已經(jīng)知道,PHP 擴(kuò)展既能構(gòu)建成靜態(tài)庫(kù)也可以構(gòu)建成動(dòng)態(tài)庫(kù)(.so
)。大多數(shù)靜態(tài)庫(kù)是與 PHP 捆綁在一起編譯的,動(dòng)態(tài)庫(kù)可以顯式地傳遞參數(shù) --enable-EXTNAME=shared
或 --with-EXTNAME=shared
給 ./configure
。
靜態(tài)擴(kuò)展默認(rèn)是可用的,動(dòng)態(tài)庫(kù)需要增加 extension 或者 zend_extension 的 ini 配置。倆者可以是絕對(duì)路徑,也可以是相對(duì)路徑。
例如編譯 PHP 擴(kuò)展用項(xiàng)目的配置項(xiàng):
~/php-src> ./configure --prefix=$HOME/myphp --enable-debug --enable-maintainer-zts --enable-opcache --with-gmp=shared
這個(gè)例子中 opcache 擴(kuò)展和 GMP 擴(kuò)展都被編譯為位于 modules/
目錄中的共享對(duì)象。 您可以通過(guò)更改extension_dir
或通過(guò)傳遞絕對(duì)路徑來(lái)加載:
~/php-src> sapi/cli/php -dzend_extension=`pwd`/modules/opcache.so -dextension=`pwd`/modules/gmp.so # or ~/php-src> sapi/cli/php -dextension_dir=`pwd`/modules -dzend_extension=opcache.so -dextension=gmp.so
在 make install
步驟中,這兩個(gè) .so
文件會(huì)被移進(jìn) PHP 安裝的擴(kuò)展目錄,你使用 php-config --extension-dir
命令可能可以找到它。對(duì)于上面的構(gòu)建選項(xiàng),它將是 /home/myuser/myphp/lib/php/extensions/no-debug-non-zts-MODULE_API
。這個(gè)值也是 extension_dir
配置選項(xiàng)的默認(rèn)值,所以你無(wú)需明確地指定它,就可以直接加載進(jìn)擴(kuò)展:
~/myphp> bin/php -dzend_extension=opcache.so -dextension=gmp.so
這給我們留下了一個(gè)問(wèn)題:你應(yīng)該使用哪種機(jī)制?共享對(duì)象使你有一個(gè)基本的 PHP 二進(jìn)制文件并通過(guò) php.ini 加載其他擴(kuò)展。發(fā)行版通過(guò)原始的 PHP 軟件包和將擴(kuò)展作為單獨(dú)的軟件包分發(fā)來(lái)利用此功能。另一方面,如果你編譯自己的 PHP 二進(jìn)制文件,則可能不需要這個(gè),因?yàn)槟阋呀?jīng)知道需要哪些擴(kuò)展。
根據(jù)經(jīng)驗(yàn),你將對(duì) PHP 本身捆綁的擴(kuò)展使用靜態(tài)鏈接,并將共享擴(kuò)展用于其他地方。原因很簡(jiǎn)單,就像你稍后看到的,構(gòu)建外部擴(kuò)展為共享對(duì)象的更容易(或至少減少了侵入性)。另一個(gè)好處是你可以在不用重新構(gòu)建 PHP 的情況下更新擴(kuò)展。
注意
如果你需要有關(guān)擴(kuò)展和 Zend 擴(kuò)展之間差異的信息,你可以查閱專門(mén)章節(jié)。
PECL,PHP 擴(kuò)展社區(qū)庫(kù),提供了大量的 PHP 擴(kuò)展。當(dāng)擴(kuò)展從主 PHP 發(fā)行版中刪除,它們通常還在 PECL中。同樣,現(xiàn)在與 PHP 捆綁一起的許多擴(kuò)展以前都是 PECL 擴(kuò)展。
除非你在 PHP 構(gòu)建的配置步驟指定 --without-pear
,否則 make install
將PECL 作為 PEAR 的一部分下載并安裝。你可以在 $PREFIX/bin
目錄下找到 pecl
腳本?,F(xiàn)在安裝擴(kuò)展很簡(jiǎn)單,就像運(yùn)行 pecl install EXTNAME
一樣,例如:
~/myphp> bin/pecl install apcu
該命令將下載、編譯并安裝 APCu 擴(kuò)展。結(jié)果會(huì)是 apcu.so
文件在擴(kuò)展目錄下,可以通過(guò)傳遞 extension=apcu.so
配置選項(xiàng)來(lái)加載此文件。
雖然 pecl install
對(duì)終端用戶非常方便,但擴(kuò)展開(kāi)發(fā)人員對(duì)它沒(méi)什么興趣。在下面,我們將會(huì)說(shuō)明兩種手動(dòng)構(gòu)建擴(kuò)展的方式:通過(guò)將其導(dǎo)入主要的 PHP 源碼樹(shù)(允許靜態(tài)鏈接)或通過(guò)外部構(gòu)建(僅共享)。
第三方擴(kuò)展和捆綁在 PHP 的擴(kuò)展之間沒(méi)有根本上的區(qū)別。因此你可以通過(guò)復(fù)制外部擴(kuò)展到 PHP 源碼樹(shù),并和通常的構(gòu)建過(guò)程一樣來(lái)構(gòu)建。我們以APCu 作為例子來(lái)演示。
首先,你要把擴(kuò)展的源代碼放到 PHP 源碼樹(shù)的 ext/EXTNAME
目錄。如果擴(kuò)展可通過(guò) Git 獲得,就像從 ext/
中克隆倉(cāng)庫(kù)一樣簡(jiǎn)單:
~/php-src/ext> git clone https://github.com/krakjoe/apcu.git
或者你也可以下載源碼壓縮包并解壓它:
/tmp> wget /tupian/20230522/apcu-4.0.2.tgz /tmp> tar xzf apcu-4.0.2.tgz /tmp> mkdir ~/php-src/ext/apcu /tmp> cp -r apcu-4.0.2/. ~/php-src/ext/apcu
該擴(kuò)展會(huì)包含一個(gè) config.m4
文件,該文件指定autoconf文件使用的特定擴(kuò)展構(gòu)建指令。 為了將它們包含在 /configure
腳本,你必須再次運(yùn)行 ./buildconf
。為了確保配置文件已經(jīng)重新生成,建議事先刪除它:
~/php-src> rm configure && ./buildconf --force
現(xiàn)在你可以使用 ./config.nice
腳本將 APCu 添加到你的現(xiàn)有配置,或者從全新的配置行開(kāi)始:
~/php-src> ./config.nice --enable-apcu # or ~/php-src> ./configure --enable-apcu # --other-options
最后,運(yùn)行 make -jN
執(zhí)行實(shí)際的構(gòu)建。由于我們沒(méi)有使用 --enable-apcu=shared
,該擴(kuò)展已經(jīng)靜態(tài)鏈接到 PHP 庫(kù),即不需要額外的操作即可使用它。顯然,你也可以使用 make install
去安裝最后的二進(jìn)制文件。
phpize
構(gòu)建擴(kuò)展還可以通過(guò)使用構(gòu)建 PHP章節(jié)提及到的 phpize
腳本與 PHP 分開(kāi)構(gòu)建。
phpize
的作用與 ./buildconf
用于 PHP 構(gòu)建的腳本相似:第一,通過(guò)$PREFIX/lib/php/build
復(fù)制文件導(dǎo)入 PHP 構(gòu)建系統(tǒng)到你的擴(kuò)展中。這些文件是 acinclude.m4
(PHP 的 M4宏)、phpize.m4
(它會(huì)在你的擴(kuò)展中重命名為 configure.in
并包含主要的構(gòu)建說(shuō)明)和 run-tests.php
。
然后 phpize
將調(diào)用 autoconf 生成 ./configure
文件,該文件可以自定義擴(kuò)展構(gòu)建。注意,沒(méi)必要傳遞 --enable-apcu
給它,因?yàn)檫@是隱式假定的。相反,你應(yīng)該使用 --with-php-config
指定你的 php-config
腳本路徑:
/tmp/apcu-4.0.2> ~/myphp/bin/phpize Configuring for: PHP Api Version: 20121113 Zend Module Api No: 20121113 Zend Extension Api No: 220121113 /tmp/apcu-4.0.2> ./configure --with-php-config=$HOME/myphp/bin/php-config /tmp/apcu-4.0.2> make -jN && make install
當(dāng)你構(gòu)建擴(kuò)展時(shí),你應(yīng)該總是指定 --with-php-config
選項(xiàng)(除非你只有一個(gè)全局的 PHP 安裝),否則 ./configure
無(wú)法確定要構(gòu)建的 PHP 版本和標(biāo)志。指定 php-config
腳本也確保了 make install
將移動(dòng)生成的 .so
文件(可以在 modules/
目錄找到)到正確的擴(kuò)展目錄。
由于在 phpize
階段還復(fù)制了 run-tests.php
文件,因此你可以使用 make test
(或顯示調(diào)用 run-tests)運(yùn)行擴(kuò)展測(cè)試。
刪除已編譯對(duì)象的 make clean
也是可用的,并且允許你增量構(gòu)建失敗時(shí)強(qiáng)制重新構(gòu)建擴(kuò)展。 另外 phpize 提供了一個(gè)清理選項(xiàng) phpize --clean
。該命令將刪除所有 phpize
導(dǎo)入的文件和通過(guò) /configure
腳本生成的文件。
PHP CLI 二進(jìn)制文件提供了幾個(gè)選項(xiàng)來(lái)顯示關(guān)于擴(kuò)展的信息。你已經(jīng)知道 -m
,該命令會(huì)列出所有已經(jīng)下載的擴(kuò)展。你可以利用它來(lái)確定擴(kuò)展是否正確下載了:
~/myphp/bin> ./php -dextension=apcu.so -m | grep apcu apcu
還有其他一些以 --r
開(kāi)頭的參數(shù)都是具有 Reflection 功能。例如,你可以使用 --ri
去顯示擴(kuò)展的配置:
~/myphp/bin> ./php -dextension=apcu.so --ri apcu apcu APCu Support => disabled Version => 4.0.2 APCu Debugging => Disabled MMAP Support => Enabled MMAP File Mask => Serialization Support => broken Revision => $Revision: 328290 $ Build Date => Jan 1 2014 16:40:00 Directive => Local Value => Master Value apc.enabled => On => On apc.shm_segments => 1 => 1 apc.shm_size => 32M => 32M apc.entries_hint => 4096 => 4096 apc.gc_ttl => 3600 => 3600 apc.ttl => 0 => 0 # ...
--re
參數(shù)列出擴(kuò)展添加的所有初始設(shè)置、常數(shù)、函數(shù)和類(lèi):
~/myphp/bin> ./php -dextension=apcu.so --re apcu Extension [ <persistent> extension #27 apcu version 4.0.2 ] { - INI { Entry [ apc.enabled <SYSTEM> ] Current = '1' } Entry [ apc.shm_segments <SYSTEM> ] Current = '1' } # ... } - Constants [1] { Constant [ boolean APCU_APC_FULL_BC ] { 1 } } - Functions { Function [ <internal:apcu> function apcu_cache_info ] { - Parameters [2] { Parameter #0 [ <optional> $type ] Parameter #1 [ <optional> $limited ] } } # ... } }
--re
參數(shù)僅適用普通擴(kuò)展,Zend 擴(kuò)展使用 --rz
代替。 你可以在 opcache 上嘗試:
~/myphp/bin> ./php -dzend_extension=opcache.so --rz "Zend OPcache" Zend Extension [ Zend OPcache 7.0.3-dev Copyright (c) 1999-2013 by Zend Technologies <http://www.zend.com/> ]
如你所見(jiàn), 該命令沒(méi)有顯示有用的信息。因?yàn)?opcache 同時(shí)注冊(cè)了普通擴(kuò)展和 Zend 擴(kuò)展, 前者包含所有初始配置、常量和函數(shù)。因此在這個(gè)特殊的案例中,你仍然需要使用 --re
。其他 Zend 擴(kuò)展通過(guò) --rz
可得到信息。
擴(kuò)展對(duì)5個(gè)主要因素非常敏感。如果它們不合適,則該擴(kuò)展將不會(huì)加載到 PHP中,并將無(wú)用:
- PHP Api 版本
- Zend 模塊 Api 編號(hào)
- Zend 擴(kuò)展 Api 編號(hào)
- 調(diào)試模式
- 線程安全
phpize 工具可讓你回想它們的一些信息。所以,如果你在調(diào)試模式下構(gòu)建 PHP,并試圖加載和使用非調(diào)試模式構(gòu)建的擴(kuò)展,那它將無(wú)法工作。其他檢查也一樣。
PHP Api 版本 是內(nèi)部 API 版本號(hào),Zend 模塊 Api 編號(hào) 和 Zend 擴(kuò)展 Api 編號(hào) 分別與 PHP 擴(kuò)展和 Zend 擴(kuò)展 API 有關(guān)。
那些編號(hào)隨后作為 C 宏傳遞給正在構(gòu)建的擴(kuò)展,以便它本身可以檢查那些參數(shù),并在 C 預(yù)處理器 #ifdef
的基礎(chǔ)上采用不同的代碼路徑。當(dāng)那些編號(hào)作為宏傳給擴(kuò)展代碼,它們會(huì)被寫(xiě)在擴(kuò)展結(jié)構(gòu)中,以便你每次嘗試在 PHP 二進(jìn)制文件中加載該擴(kuò)展時(shí),都將對(duì)照 PHP 二進(jìn)制文件本身的編號(hào)進(jìn)行檢查。如果不匹配,那么該擴(kuò)展不會(huì)被加載,并顯示一條錯(cuò)誤信息。
如果我們看一下擴(kuò)展的 C 結(jié)構(gòu),它看起來(lái)像這樣:
zend_module_entry foo_module_entry = { STANDARD_MODULE_HEADER, "foo", foo_functions, PHP_MINIT(foo), PHP_MSHUTDOWN(foo), NULL, NULL, PHP_MINFO(foo), PHP_FOO_VERSION, STANDARD_MODULE_PROPERTIES };
至今,對(duì)我們來(lái)說(shuō)有趣的是 STANDARD_MODULE_HEADER
宏。如果我們擴(kuò)展它,我們可以看到:
#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS #define STANDARD_MODULE_HEADER STANDARD_MODULE_HEADER_EX, NULL, NULL
注意 ZEND_MODULE_API_NO
、ZEND_DEBUG
、 USING_ZTS
是如何使用的。
如果查看 PHP 擴(kuò)展的默認(rèn)目錄,它應(yīng)該像 no-debug-non-zts-20090626
。如你所料,該目錄由不同的部分組成:調(diào)試模式,其次是線程安全信息,然后是Zend 模塊 Api 編號(hào)。所以默認(rèn)情況下,PHP 試圖幫你瀏覽擴(kuò)展。
注意
通常,當(dāng)你成為一位內(nèi)部開(kāi)發(fā)人員或擴(kuò)展開(kāi)發(fā)人員,必須使用調(diào)試參數(shù),并且如果必須處理 Windows 平臺(tái),線程也會(huì)顯示出來(lái)。你可以針對(duì)那些參數(shù)的多種情況多次編譯同一擴(kuò)展。
記住,每次新的 PHP 主要/次要版本都會(huì)更改參數(shù),比如 PHP Api 版本,這就是為什么你需要針對(duì)新的 PHP 版本重新編譯的原因。
> /path/to/php70/bin/phpize -v Configuring for: PHP Api Version: 20151012 Zend Module Api No: 20151012 Zend Extension Api No: 320151012 > /path/to/php71/bin/phpize -v Configuring for: PHP Api Version: 20160303 Zend Module Api No: 20160303 Zend Extension Api No: 320160303 > /path/to/php56/bin/phpize -v Configuring for: PHP Api Version: 20131106 Zend Module Api No: 20131226 Zend Extension Api No: 220131226
注意
Zend 模塊 Api 編號(hào) 本身是使用 年 月 日 的日期格式構(gòu)建。這是 API 更改和并被標(biāo)記的日期。Zend 擴(kuò)展 Api 編號(hào) 是 Zend 版本,其次是 Zend 模塊 Api 編號(hào)。
注意
數(shù)字太多?是的,一個(gè) API 編號(hào)綁定一個(gè) PHP 版本,對(duì)任何人來(lái)說(shuō)都足夠了,并且可以簡(jiǎn)化對(duì) PHP 的理解。不幸的是,除了 PHP 版本本身,還增加了3種不同的 API 編號(hào)。你應(yīng)該找哪一個(gè)?答案是任何一個(gè):當(dāng) PHP 版本演變時(shí),它們?nèi)N同時(shí)演變。由于歷史原因,我們有三種不同編號(hào)。
但是,你是一位 C開(kāi)發(fā)人員,不是嗎?為什么不根據(jù)這些數(shù)字構(gòu)建一個(gè)“兼容的”頭文件?我們?cè)谖覀兊臄U(kuò)展中使用了類(lèi)似這些:
#include "php.h" #include "Zend/zend_extensions.h" #define PHP_5_5_X_API_NO 220121212 #define PHP_5_6_X_API_NO 220131226 #define PHP_7_0_X_API_NO 320151012 #define PHP_7_1_X_API_NO 320160303 #define PHP_7_2_X_API_NO 320160731 #define IS_PHP_72 ZEND_EXTENSION_API_NO == PHP_7_2_X_API_NO #define IS_AT_LEAST_PHP_72 ZEND_EXTENSION_API_NO >= PHP_7_2_X_API_NO #define IS_PHP_71 ZEND_EXTENSION_API_NO == PHP_7_1_X_API_NO #define IS_AT_LEAST_PHP_71 ZEND_EXTENSION_API_NO >= PHP_7_1_X_API_NO #define IS_PHP_70 ZEND_EXTENSION_API_NO == PHP_7_0_X_API_NO #define IS_AT_LEAST_PHP_70 ZEND_EXTENSION_API_NO >= PHP_7_0_X_API_NO #define IS_PHP_56 ZEND_EXTENSION_API_NO == PHP_5_6_X_API_NO #define IS_AT_LEAST_PHP_56 (ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO && ZEND_EXTENSION_API_NO < PHP_7_0_X_API_NO) #define IS_PHP_55 ZEND_EXTENSION_API_NO == PHP_5_5_X_API_NO #define IS_AT_LEAST_PHP_55 (ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO && ZEND_EXTENSION_API_NO < PHP_7_0_X_API_NO) #if ZEND_EXTENSION_API_NO >= PHP_7_0_X_API_NO #define IS_PHP_7 1 #define IS_PHP_5 0 #else #define IS_PHP_7 0 #define IS_PHP_5 1 #endif
看見(jiàn)了?
或者更簡(jiǎn)單(更好)的是使用 PHP_VERSION_ID
,這你可能更熟悉:
#if PHP_VERSION_ID >= 50600
看完了這篇文章,相信你對(duì)編譯PHP擴(kuò)展的方法是什么有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!
網(wǎng)站名稱:編譯PHP擴(kuò)展的方法是什么-創(chuàng)新互聯(lián)
標(biāo)題URL:http://www.rwnh.cn/article48/pcohp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、虛擬主機(jī)、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容