PHP擴(kuò)展編寫方法

本方案中采用的PHP擴(kuò)展方式為:

?下載PHP對(duì)應(yīng)版本的源碼趁尼,在其中加入、生成擴(kuò)展(如smsupport.so);

?然后針對(duì)安裝同一版本的PHP(注意眨业,不需要是源碼安裝的,可以通過yum install沮协,apt-get install安裝的)龄捡,將smsupport.so放置到extension_dir中;在php.ini最后一行加入extension = smsupport.so慷暂;

?重啟apached服務(wù)

?此后聘殖,在php文件中直接調(diào)用smsupport.so提供的方法即可晨雳。

注意點(diǎn)

?在進(jìn)行擴(kuò)展及測(cè)試的過程中我們需要設(shè)置PHP的SAFE_MODE為OFF,否則可能無法完成擴(kuò)展或測(cè)試奸腺。SAFE_MODE默認(rèn)為OFF餐禁。

?編譯php擴(kuò)展的環(huán)境和運(yùn)行環(huán)境需要一致!

?建議先使用PHP執(zhí)行腳本突照,此時(shí)提供錯(cuò)誤信息較為豐富帮非。

PHP擴(kuò)展開發(fā)

1.從http://php.net/releases/ php中下載對(duì)應(yīng)目標(biāo)的PHP版本;

2.由于php依賴libxml2-dev讹蘑,為此末盔,首先通過apt-get install libxml2-dev或者yum install libxml2-dev(注libxml2-dev在不同Linux下名稱不同,baidu下)

3.解壓縮1中下載的php包座慰,進(jìn)入目錄陨舱,運(yùn)行./configure完成配置,此時(shí)會(huì)生成編寫extension所需的一些文件

4.進(jìn)入到php源碼中的ext目錄版仔,執(zhí)行./ext_skel --extname=smsupport游盲,其會(huì)自動(dòng)生成一系列目錄及目錄內(nèi)的文件

5.在ext/smsupport目錄中

a)在.c文件中找到const zend_function_entry cqwei_functions[] = {,在其后添加自己定義的函數(shù)

注意:自動(dòng)生成的為c文件蛮粮,由于本擴(kuò)展中要用到cpp益缎,強(qiáng)行將其改為cpp,在編譯時(shí)在后端加上-lstdc++然想,使得編譯成功

PHP_FE(testadd,NULL)/*For testing, remove later. */

PHP_FE(dcsSM2Verify,arg_dcsSM2Verify)

PHP_FE(dcsSM4Decrypt,arg_dcsSM4Decrypt)

注意點(diǎn):

ü將PHP_FE的名稱改成自己的函數(shù)链峭,可以同時(shí)包含多個(gè);

ü如果PHP_FE中包含的函數(shù)需要參數(shù)又沾,則應(yīng)加入?yún)?shù)信息弊仪,如arg_Verify,其中arg_Verify包含4個(gè)參數(shù)杖刷,arg_Decrypt包含2個(gè)參數(shù)励饵。

nZEND_BEGIN_ARG_INFO_EX(arg_Verify,

0, 0, 1)

ZEND_ARG_INFO(0,user)

ZEND_ARG_INFO(0,pubKey)

ZEND_ARG_INFO(0,ticket)

ZEND_ARG_INFO(0,sig)

ZEND_END_ARG_INFO()

nZEND_BEGIN_ARG_INFO_EX(arg_Decrypt,0, 0, 1)

ZEND_ARG_INFO(0,key)

ZEND_ARG_INFO(0,cipher)

ZEND_END_ARG_INFO()

b)PHP_FUNCTION(testadd)在定義自定義函數(shù)testadd的函數(shù)體,如下所示為最簡(jiǎn)單的內(nèi)容

PHP_FUNCTION(testadd)

{

zend_printf("testadd00");

}

c)PHP_FUNCTION(Verify)滑燃,稍微復(fù)雜役听,因?yàn)橛袇?shù)和返回值,示例如下

PHP_FUNCTION(Verify)

{

char * user;

char * pubKey;

char* ticket;

char * sig;

intuserLen,pubKeyLen,ticketLen,sigLen;

charpubKeyArray[64];

if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"ssss",&user,&userLen,&pubKey,&pubKeyLen,&ticket,&ticketLen,&sig,&sigLen)== FAILURE)

{//解析參數(shù)表窘,參數(shù)為4個(gè)char *典予,s表示char

*,其他格式見下文中的表格

RETURN_FALSE;

return;

}

if(pubKeyLen != 128 || sigLen !=64)

{

zend_printf("the sm2 parameter isincorrect\n");

RETURN_FALSE;

return;

}

CECCPublicKey *verify = new CECCPublicKey();

loadHexStr(pubKey,(unsigned char *)pubKeyArray,64);

if(verify->SetPublicKey((constunsigned char*)pubKeyArray, 64) == 0)

{

zend_printf("the public key isincorrect\n");

delete verify;

RETURN_FALSE;//表示返回false

return;

}

if(verify->VerifyMessage((constunsigned char *)ticket, ticketLen, (const unsigned char *)sig, sigLen, (constchar *)user, userLen) != 1)

{

zend_printf("the signature is incorrect\n");

delete verify;

RETURN_FALSE;

return;

}

delete verify;

RETURN_TRUE;//表示返回true

return;

}

d)char *plain = emalloc(cipherLen);

efree (plain);//動(dòng)態(tài)分配內(nèi)存和釋放

e)返回string變量RETVAL_STRINGL(plain, cipherLen, 1); plain為char *乐严,cipherLen為長(zhǎng)度

f)在.h文件中加入如下內(nèi)容

PHP_FUNCTION(testadd);

PHP_FE(Verify);

PHP_FE(Decrypt);

g)在php源碼/ext/smsupport下編譯:cc -fpic -DCOMPILE_DL_SMSUPPORT=1 -I /usr/local/include -I../ -I../../main -I ../.. -I ../../TSRM -I ../../Zend -c smsupport.cppEllipticCurve.cpp sm3hash.cpp Mpi.cpp SMS4.cpp -lstdc++ -fpermissive-Wwrite-strings

其中除smsupport.cpp外為正常的cpp文件

h)在php源碼/ext/smsupport下鏈接:cc -shared -L /usr/local/lib -rdynamic -o smsupport.so *.o -lstdc++

部署示例

1.在CentOS上搭建php+apache

a)Yum install php

b)Yum install httpd

c)Service httpd start

2.配置php

a)將上述生成的so文件(如smsupport.so)放置到extension_dir目錄中瘤袖,extension_dir路徑可通過echo phpinfo()獲取

b)Find / -name “php.ini”,加入extension

cqwei.so;(在較為靠后的位置加入)

c)Service httpd start

d)在php中直接調(diào)用方法即可

細(xì)節(jié)介紹

?zend_parse_parameters

n如if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"ssss",&user,&userLen,&pubKey,&pubKeyLen,&ticket,&ticketLen,&sig,&sigLen)== FAILURE)

nZEND_NUM_ARGS()告訴Zend引擎要取得的參數(shù)的信息

nTSRMLS_CC用來確保線程安全

n返回值將被檢查是SUCCESS還是FAILURE昂验。

u通常情況下捂敌,zend_parse_parameters()將返回SUCCESS艾扮;

u然而,如果調(diào)用腳本試圖傳入太多或太少的參數(shù)占婉,或者傳入的參數(shù)不能被轉(zhuǎn)為適當(dāng)?shù)念愋团葑欤琙end會(huì)自動(dòng)輸出一條錯(cuò)誤信息并優(yōu)雅地將控制權(quán)還給調(diào)用腳本

n本例指定s表明此函數(shù)期望只傳入一個(gè)參數(shù),而且該參數(shù)應(yīng)該被轉(zhuǎn)為string數(shù)據(jù)類型并裝入通過地址傳入的char*變量逆济。

n注意酌予,還有一個(gè)int變量通過地址被傳入zend_parse_parameters()。這使Zend引擎提供字符串的字節(jié)長(zhǎng)度奖慌,如此二進(jìn)制安全的函數(shù)不再需要依賴strlen(name)確定字符串的長(zhǎng)度抛虫。實(shí)際上使用strlen(name)甚至得不到正確的結(jié)果,因?yàn)閚ame可能在字符串結(jié)束之前包含一個(gè)或多個(gè)NULL字符升薯。

n再比如if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld|b", &a,&b, &return_long) == FAILURE) {

u這次你的數(shù)據(jù)類型字符串讀起來像:“我要一個(gè)long(l)莱褒,一個(gè)double(d)”击困。

u下一個(gè)管道字符表示其余的參數(shù)是可選的涎劈。如果函數(shù)調(diào)用時(shí)沒有傳入可選參數(shù),那么zend_parse_parameters()將不會(huì)改變傳給它的對(duì)應(yīng)變量阅茶。

lb是用于Boolean蛛枚。

u數(shù)據(jù)類型字符串后面的是a、b和return_long脸哀,它們按地址傳遞蹦浦,這樣zend_parse_parameters()可以將值裝入它們。

u警告:在32位平臺(tái)中經(jīng)常不加區(qū)分地使用int和long撞蜂,但是盲镶,當(dāng)你的代碼在64位硬件上編譯時(shí),在本該使用一個(gè)的地方使用另一個(gè)是很危險(xiǎn)的蝌诡。所以記住要把long用于整型溉贿,把int用于字符串的長(zhǎng)度。

?表1顯示不同的類型和對(duì)應(yīng)的字母代碼浦旱,以及可用于zend_parse_parameters()的C類型:

類型代碼變量類型

Booleanbzend_bool

Longllong

Doubleddouble

Stringschar*, int

Resourcerzval*

Arrayazval*

Objectozval*

zvalzzval*

n你可能立刻注意到表1中的最后四個(gè)類型都是zval*宇色。待會(huì)兒你將看到,PHP中實(shí)際使用zval數(shù)據(jù)類型存儲(chǔ)所有的用戶空間變量颁湖。三種“復(fù)雜”數(shù)據(jù)類型宣蠕,資源、數(shù)組和對(duì)象甥捺,當(dāng)它們的數(shù)據(jù)類型代碼被用于zend_parse_parameters()時(shí)抢蚀,Zend引擎會(huì)進(jìn)行類型檢查,但是因?yàn)樵贑中沒有與它們對(duì)應(yīng)的數(shù)據(jù)類型镰禾,所以不會(huì)執(zhí)行類型轉(zhuǎn)換思币。

?返回值

n返回值的設(shè)置方法鹿响,網(wǎng)上大多數(shù)是錯(cuò)誤的,可以借鑒ext目錄下其他的擴(kuò)展谷饿。

mcrypt安裝

?首先安裝mcrypt:http://blog.csdn.net/zy112289/article/details/52840062

l先安裝Libmcrypt

#tar -zxvf libmcrypt-2.5.8.tar.gz

#cd libmcrypt-2.5.8

#./configure

#make

#make install說明:libmcript默認(rèn)安裝在/usr/local

l安裝mhash

#tar -zxvf mhash-0.9.9.9.tar.gz

#cd mhash-0.9.9.9

#./configure

#make

#make install

l安裝mcrypt

#tar -zxvf mcrypt-2.6.8.tar.gz

#cd mcrypt-2.6.8

#LD_LIBRARY_PATH=/usr/local/lib ./configure//注意惶我,在一行輸入

#make

#make install

?安裝phpize: yum install php-devel

?編譯、安裝mcrypt

ncd php-5.3.3/ext/mcrypt/

nphpize

n./configure --with-php-config=/usr/bin/php-config

nmake && make install

n提示:Installing shared extensions:/usr/lib64/php/modules/博投,說明安裝成功

n在php.ini中加入extension = mcrypt.so以加入擴(kuò)展绸贡。

?$

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市毅哗,隨后出現(xiàn)的幾起案子听怕,更是在濱河造成了極大的恐慌,老刑警劉巖虑绵,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尿瞭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡翅睛,警方通過查閱死者的電腦和手機(jī)声搁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捕发,“玉大人疏旨,你說我怎么就攤上這事≡幔” “怎么了檐涝?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)法挨。 經(jīng)常有香客問我谁榜,道長(zhǎng),這世上最難降的妖魔是什么凡纳? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任窃植,我火速辦了婚禮,結(jié)果婚禮上惫企,老公的妹妹穿的比我還像新娘撕瞧。我一直安慰自己,他們只是感情好狞尔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布丛版。 她就那樣靜靜地躺著,像睡著了一般偏序。 火紅的嫁衣襯著肌膚如雪页畦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天研儒,我揣著相機(jī)與錄音豫缨,去河邊找鬼独令。 笑死,一個(gè)胖子當(dāng)著我的面吹牛好芭,可吹牛的內(nèi)容都是我干的燃箭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼舍败,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼招狸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邻薯,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤裙戏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厕诡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體累榜,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年灵嫌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壹罚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甲献。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宏胯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稠曼,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布客年,位于F島的核電站霞幅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏量瓜。R本人自食惡果不足惜司恳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绍傲。 院中可真熱鬧扔傅,春花似錦、人聲如沸烫饼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杠纵。三九已至荠耽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間比藻,已是汗流浹背铝量。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工倘屹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慢叨。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓纽匙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親拍谐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哄辣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容