欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          php入門到就業(yè)線上直播課:進(jìn)入學(xué)習(xí)
          Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點(diǎn)擊使用

          眾所周知,作為一名phper,對php有限的功能感到尷尬,比如:調(diào)用ffmpeg視頻處理工具。沒有專門的擴(kuò)展來操作的,什么?利用php system函數(shù)調(diào)用?對于開源的php腳本,這太不安全了!

          這個(gè)時(shí)候作為深資的phper會考慮開發(fā)php擴(kuò)展,在擴(kuò)展中實(shí)現(xiàn)對ffmpeg的操作。

          目前c站上對于rust如何開發(fā)php擴(kuò)展的文章幾乎沒有,就連開發(fā)php擴(kuò)展流程的文章也都很對付。特此撰寫此文?。?!

          為什么要使用php擴(kuò)展?

          優(yōu)點(diǎn):

          1、php擴(kuò)展是C開發(fā)的,那速度沒得說。

          2、耦合性高,它的出現(xiàn)就是用來增強(qiáng)php的。

          3、安全性高,畢竟擴(kuò)展是編譯后的程序,代碼不開源。

          缺點(diǎn):

          1、需針對php版本及系統(tǒng)環(huán)境進(jìn)行開發(fā),那么就比較麻煩了。也就是說7.4版本的php,liunx環(huán)境下開發(fā)的擴(kuò)展,只支持該php版本及系統(tǒng)。

          2、需要會C、C++,當(dāng)然本文是以rust進(jìn)行開發(fā),對C的數(shù)據(jù)類型進(jìn)行了解,對rust FFI的操作及數(shù)據(jù)類型轉(zhuǎn)換需精通。

          3、調(diào)試相對麻煩。

          為什么要用rust開發(fā)php擴(kuò)展?

          原因很簡單,這還要說起rust的語言特性。

          1、因“所有權(quán)”的特性使你的程序更安全,不會像C那樣出現(xiàn)各種“玄學(xué)BUG”。

          2、擁有C一樣的性能。

          3、畢竟是最受歡迎的語言,我很看好它的發(fā)展。

          rust開發(fā)php擴(kuò)展流程:

          當(dāng)然,rust目前是沒有專門開發(fā)php擴(kuò)展的骨架。所以我的邏輯也很簡單,利用rust開發(fā)靜態(tài)庫暴露給C【涉及FFI的了解】。我們在php官方骨架中直接引入rust靜態(tài)庫調(diào)用其方法即可。

          開發(fā)環(huán)境

          寶塔【CentOS 7.6】、GCC【涉及php擴(kuò)展骨架的編譯,我這里系統(tǒng)內(nèi)置就有,如果編譯擴(kuò)展報(bào)相關(guān)錯(cuò)了自行安裝】、對應(yīng)php版本源碼、web環(huán)境【寶塔中安裝對應(yīng)php版本、nginx、mysql等等】

          開發(fā)整體流程:

          1、準(zhǔn)備寶塔

          寶塔安裝流程:CentOS寶塔搭建(超詳細(xì))_一碼超人的博客-CSDN博客_centos 寶塔

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          這里我們以開發(fā)php7.4擴(kuò)展為例。

          2、下載php7.4 liunx版源碼

          php官網(wǎng):PHP: Hypertext Preprocessor

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          注意!該源碼版本必須與你環(huán)境php版本完全一致!?。?/strong>

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          下載完畢:

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          3、上傳php源碼到寶塔

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          /usr/phper
          登錄后復(fù)制

          在usr下創(chuàng)建一個(gè)phper文件夾,然后將源碼壓縮包上傳到此處。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          解壓該壓縮包

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          4、創(chuàng)建一個(gè)我們自己的擴(kuò)展

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          /usr/phper/php-7.4.30/ext目錄下有這么一個(gè)php文件,它可以創(chuàng)建擴(kuò)展!

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          注意設(shè)置命令行版本,因?yàn)榻酉聛砝胮hp命令必須是版本一致的!

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          在剛剛的目錄下,點(diǎn)擊終端,輸入創(chuàng)建擴(kuò)展命令。

          php ext_skel.php --ext 擴(kuò)展名稱
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          這里就多出了一個(gè)新的擴(kuò)展源碼文件。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          在該目錄下點(diǎn)擊終端,輸入:

          phpize
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          接著輸入:

          ./configure --with-php-config=/www/server/php/74/bin/php-config
          登錄后復(fù)制

          注意這個(gè)參數(shù)php路徑,如果是別的版本,請自行在寶塔里安裝找到對應(yīng)版本路徑,它們都是放一起的。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          回車開始進(jìn)行檢查了

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          最后輸入:

          make
          登錄后復(fù)制

          進(jìn)行編譯。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          這個(gè)目錄下便是編譯出來的so擴(kuò)展最終文件了!

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          讓我們看下默認(rèn)生成的擴(kuò)展有哪些功能

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          查看主文件【需了解php擴(kuò)展骨架,這里以它默認(rèn)給的為例】

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          也就是說,剛剛編譯出來的擴(kuò)展,是有這兩個(gè)函數(shù)的,咱們測試一下玩玩。

          注意!每次修改主文件,都需要重新按上述命令跑一遍,否則不生效,很奇怪!

          phpize ./configure --with-php-config=/www/server/php/74/bin/php-config make
          登錄后復(fù)制

          登錄后復(fù)制

          5、使用擴(kuò)展

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          復(fù)制剛剛生成的擴(kuò)展文件到我們php環(huán)境的擴(kuò)展里

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          配置php.ini加載hello.so擴(kuò)展

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          extension = hello.so
          登錄后復(fù)制

          保存后記得重新啟動下php,否則不生效的!

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          在文件管理中點(diǎn)擊終端,輸入:

          php -m
          登錄后復(fù)制

          可以看到我們的擴(kuò)展在列表中了。

          創(chuàng)建一個(gè)站點(diǎn),測試下擴(kuò)展中兩個(gè)函數(shù)。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          看好,php版本是7.4

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          訪問站點(diǎn)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          沒有問題哦!

          當(dāng)然也可以通過命令行運(yùn)行php腳本查看結(jié)果【前提是網(wǎng)站那里php命令行版本設(shè)置的7.4】

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          php index.php
          登錄后復(fù)制

          OK!從創(chuàng)建到生成到使用擴(kuò)展的流程結(jié)束,接下來才進(jìn)入正題,開始用rust開發(fā)擴(kuò)展。

          6、rust與php擴(kuò)展的整合開發(fā)

          開發(fā)工具:CLion

          需要rust環(huán)境與CLion中rust插件的安裝與配置,這個(gè)自行去百度,比我想象中的全!

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          創(chuàng)建一個(gè)hello命名的庫項(xiàng)目

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          我們寫兩個(gè)導(dǎo)出函數(shù),分別是加法功能和base64字符串解析功能。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          lib.rs

          #![crate_type = "staticlib"]  extern crate libc;  //使用C類型約束 use std::ffi::{CStr, CString}; use libc::{c_char, c_int};  //add_int【參數(shù):兩個(gè)c語言的int類型】:對兩個(gè)int類型數(shù)值進(jìn)行相加 #[no_mangle] pub extern "C" fn add_int(x:c_int, y:c_int) -> c_int{     //兩個(gè)數(shù)相加     return x + y; }  //base64_decode函數(shù)【參數(shù):c語言的*char類型】:對字符串進(jìn)行base64解碼 #[no_mangle] pub extern "C" fn base64_decode(s:*const c_char) -> *mut c_char {     //c char類型轉(zhuǎn)&str     let h = unsafe{CStr::from_ptr(s).to_str().unwrap()};     //base64 解碼     let s = base64::decode(h.to_string());     if let Err(_s) = s {         panic!("類型錯(cuò)誤!");     }     let n = String::from_utf8(s.unwrap().clone()).unwrap();     //String 轉(zhuǎn) C CString     let a = CString::new(n.as_str()).unwrap();     //C CString 轉(zhuǎn) C char     //這里實(shí)屬無奈,因?yàn)閞ust ffi中闡述,對字符串返回只能是該字符串地址,所以需要該方法進(jìn)行返回C才能接收到!     let r = a.into_raw();     return r; }
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          Cargo.toml

          [package] name = "hello" version = "0.1.0" edition = "2021"  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] name = "hello" crate-type = ["staticlib"]  [dependencies] libc = "*" base64 = "0.12.1"
          登錄后復(fù)制

          注意在編譯過程中涉及系統(tǒng)類型,不然在引入該靜態(tài)庫編譯擴(kuò)展可能報(bào)錯(cuò),提示不支持。

          編譯64位靜態(tài)庫

          rustup target add x86_64-unknown-linux-musl cargo build --target x86_64-unknown-linux-musl --release
          登錄后復(fù)制

          編譯32位靜態(tài)庫

          rustup target add i686-unknown-linux-musl cargo build --target i686-unknown-linux-musl --release
          登錄后復(fù)制

          這里我們是64位系統(tǒng)。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          會生成一個(gè).a文件,該文件便是liunx支持的靜態(tài)庫文件。

          生成支持C語言的膠水頭文件【用于C調(diào)用該庫需要寫的函數(shù)聲明,很方便】

          創(chuàng)建cbindgen.toml文件

          內(nèi)容:

          language = "C"
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          安裝cbindgen,創(chuàng)建頭文件。

          cargo install --force cbindgen cbindgen --config cbindgen.toml --crate 項(xiàng)目名稱 --output 頭文件名稱.h
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          自動生成了C語言的函數(shù)聲明hello.h文件,用于調(diào)用。

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          回到之前我們創(chuàng)建的hello擴(kuò)展

          創(chuàng)建lib文件夾

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          將剛剛編譯出來的靜態(tài)庫.a文件上傳到lib目錄下

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          將剛剛創(chuàng)建的.h頭文件上傳到擴(kuò)展目錄下

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          配置.m4預(yù)編譯文件【關(guān)鍵】

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          設(shè)置引入lib文件夾中的靜態(tài)庫文件一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

            PHP_ADD_LIBRARY_WITH_PATH(hello, /usr/phper/php-7.4.30/ext/hello/lib, HELLO_SHARED_LIBADD)   PHP_SUBST(HELLO_SHARED_LIBADD)
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          保存.m4

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          編寫主文件

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          /* hello extension for PHP */  #ifdef HAVE_CONFIG_H # include "config.h" #endif  #include "php.h" #include "ext/standard/info.h" #include "php_hello.h" #include "hello.h"//引入頭文件 /* For compatibility with older PHP versions */ #ifndef ZEND_PARSE_PARAMETERS_NONE #define ZEND_PARSE_PARAMETERS_NONE()  	ZEND_PARSE_PARAMETERS_START(0, 0)  	ZEND_PARSE_PARAMETERS_END() #endif  /* {{{ void hello_test1()  */ PHP_FUNCTION(hello_test1) { 	ZEND_PARSE_PARAMETERS_NONE();      int num = add_int(1,2);//rust中兩個(gè)數(shù)相加函數(shù)并返回。      	php_printf("The extension %d is loaded and working!rn", num); } /* }}} */  /* {{{ string hello_test2( [ string $var ] )  */ PHP_FUNCTION(hello_test2) { 	char *var = "World"; 	size_t var_len = sizeof("World") - 1; 	zend_string *retval;  	ZEND_PARSE_PARAMETERS_START(0, 1) 		Z_PARAM_OPTIONAL 		Z_PARAM_STRING(var, var_len) 	ZEND_PARSE_PARAMETERS_END();      char *newstr = base64_decode(var);//rust中解析base64字符串并返回。      	retval = strpprintf(0, "Hello %s", newstr);  	RETURN_STR(retval); } /* }}}*/  /* {{{ PHP_RINIT_FUNCTION  */ PHP_RINIT_FUNCTION(hello) { #if defined(ZTS) && defined(COMPILE_DL_HELLO) 	ZEND_TSRMLS_CACHE_UPDATE(); #endif  	return SUCCESS; } /* }}} */  /* {{{ PHP_MINFO_FUNCTION  */ PHP_MINFO_FUNCTION(hello) { 	php_info_print_table_start(); 	php_info_print_table_header(2, "hello support", "enabled"); 	php_info_print_table_end(); } /* }}} */  /* {{{ arginfo  */ ZEND_BEGIN_ARG_INFO(arginfo_hello_test1, 0) ZEND_END_ARG_INFO()  ZEND_BEGIN_ARG_INFO(arginfo_hello_test2, 0) 	ZEND_ARG_INFO(0, str) ZEND_END_ARG_INFO() /* }}} */  /* {{{ hello_functions[]  */ static const zend_function_entry hello_functions[] = { 	PHP_FE(hello_test1,		arginfo_hello_test1) 	PHP_FE(hello_test2,		arginfo_hello_test2) 	PHP_FE_END }; /* }}} */  /* {{{ hello_module_entry  */ zend_module_entry hello_module_entry = { 	STANDARD_MODULE_HEADER, 	"hello",					/* Extension name */ 	hello_functions,			/* zend_function_entry */ 	NULL,							/* PHP_MINIT - Module initialization */ 	NULL,							/* PHP_MSHUTDOWN - Module shutdown */ 	PHP_RINIT(hello),			/* PHP_RINIT - Request initialization */ 	NULL,							/* PHP_RSHUTDOWN - Request shutdown */ 	PHP_MINFO(hello),			/* PHP_MINFO - Module info */ 	PHP_HELLO_VERSION,		/* Version */ 	STANDARD_MODULE_PROPERTIES }; /* }}} */  #ifdef COMPILE_DL_HELLO # ifdef ZTS ZEND_TSRMLS_CACHE_DEFINE() # endif ZEND_GET_MODULE(hello) #endif
          登錄后復(fù)制

          刪除之前生成的擴(kuò)展文件

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          重新生成擴(kuò)展一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          phpize ./configure --with-php-config=/www/server/php/74/bin/php-config make
          登錄后復(fù)制

          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          大小都變了,說明我們的靜態(tài)庫在里面了哈哈。

          按上述使用擴(kuò)展流程替換擴(kuò)展

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          注意!替換擴(kuò)展文件后要重啟PHP哦,不然不生效!

          7、測試rust開發(fā)的php擴(kuò)展

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          網(wǎng)頁測試

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          命令行測試

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          也可以通過php擴(kuò)展骨架直接進(jìn)行測試

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          編寫要執(zhí)行測試的擴(kuò)展函數(shù)

          --TEST-- hello_test2() Basic test --SKIPIF-- <?php if (!extension_loaded('hello')) { 	echo 'skip'; } ?> --FILE-- <?php hello_test1(); var_dump(hello_test2('5LiA56CB6LaF5Lq6')); ?> --EXPECT-- string(11) "Hello World" string(9) "Hello PHP"
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          擴(kuò)展目錄下直接輸入:

          make test
          登錄后復(fù)制

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          執(zhí)行后 tests目錄下輸出了一個(gè).out文件

          一文詳解Rust怎么開發(fā)PHP擴(kuò)展(Liunx版)

          是不是這樣更方便了呢?

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號