摘要:下面是該擴展函數的源碼。下面是該擴展函數的源碼測試引用類型參數注冊該擴展函數的代碼如下測試代碼如果直接輸入常量,會導致類型檢測通不過,觸發。
PHP擴展是高級PHP程序員必須了解的技能之一,對于一個初入門的PHP擴展開發者,怎么才能開發一個成熟的擴展,進入PHP開發的高級領域呢?本系列開發教程將手把手帶您從入門進入高級階段。
本教程系列在linux下面開發(推薦使用centos),php版本用的是5.6,并假設您有一定的linux操作經驗和c/c++基礎。
有問題需要溝通的朋友請加QQ技術交流群32550793和我溝通。
繼續上一節的內容,講解擴展函數的參數類型,下面教程內容的相關源碼已經上傳到github上面,見param子目錄下的演示代碼。
git clone https://github.com/elvisszhang/phpcpp_demo.git cd param一、代碼演示:對象類作為參數的用法
我們這里使用php的DateTime類作為擴展函數的參數來演示如何傳入對象。
下面是該擴展函數的C++源碼。
//演示時間類型操作 void pm_datetype(Php::Parameters ¶ms) { Php::Value time = params[0]; Php::out <<"param type is : " << time.type() << std::endl; Php::out <<"current time is : " << time.call("format","Y-m-d H:i:s") << std::endl; }
注冊擴展函數的代碼
myExtension.add("pm_datetype", { /**** "time" : 表示參數名稱,用于返回的異常信息中使用 "DateTime":參數對象的類名 true :表示該參數是必須的 ****/ Php::ByVal("time", "DateTime", true) });
PHP測試代碼(test/3.php)
執行測試代碼,結果如下
# php test/3.php -----TEST pm_datetype($time)----- 2018-04-17 19:57:57 -----TEST pm_datetype("2018-04-17")----- PHP Catchable fatal error: Argument 1 passed to pm_datetype() must be an instance of DateTime, string given in /data/develop/phpcpp_param/test/3.php on line 7
根據測試結果可見:
參數類型指定為特定類的對象后,傳入其他類型參數將觸發生成一個fatal error
可以使用 Php::Value的 call方法來執行對象類的函數方法,非常方便。
二、代碼演示:匿名函數或函數名稱作為參數類型大家知道c++的模板類可以讓同一個類可以處理各種不同數據類型,非常強大。
下面實現一個冒泡排序算法,使用匿名函數作為參數,讓這個冒泡排序算法也能夠對各種不同類型元素的數組都能進行排序,而且不管正向反向,數字還是文本或者是復雜結構元素都能排序。
下面是該擴展函數的C++源碼
//演示通用的冒泡排序類 Php::Value pm_sort(Php::Parameters ¶ms){ int i,j; Php::Value array = params[0]; Php::Value cmpfunc = params[1]; int len = array.size(); Php::Value result,temp; for(i=0;i注冊該擴展函數的代碼如下
myExtension.add("pm_sort", { Php::ByVal("a", Php::Type::Array), //第一個是數組類型 Php::ByVal("b", Php::Type::Callable) //第二個是函數類型 }); PHP測試代碼(test/4.php)
$a則往上冒泡,所以是降序排列 return $b > $a; }); echo var_export($result); echo PHP_EOL . "-----數字升序排列-----" . PHP_EOL; $result = pm_sort(array(22,3,15),function($a,$b){ //$b < $a 則往上冒泡,所以是升序排列 return $b < $a; }); echo var_export($result); echo PHP_EOL . "-----學生成績降序排列-----" . PHP_EOL; $score = array( array("name" => "張三", "score"=>78), array("name" => "李四", "score"=>98), array("name" => "王五", "score"=>88), ); $result = pm_sort($score,function($a,$b){ //$b["score"] > $a["score"] 則往上冒泡,所以是按成績進行降序排列 return $b["score"] > $a["score"]; }); echo var_export($result); echo PHP_EOL . "-----字符串按長度升序排列-----" . PHP_EOL; function cmp_strlen($a,$b){ //strlen($b) < strlen($a) 則往上冒泡,所以是按字符串長度進行升序排列 return strlen($b) < strlen($a); } $result = pm_sort(array("country","I","love","my"),"cmp_strlen"); echo var_export($result); echo PHP_EOL . "-----名字按首字母升序排列-----" . PHP_EOL; class MyNameSort{ public static function cmpLetter($a,$b){ //首字母asscii碼小的,則往上冒泡,所以是按首字母進行升序排列 return ord($b[0]) < ord($a[0]); } } $result = pm_sort(array("Jack","Tom","Michael","Smith"),"MyNameSort::cmpLetter"); echo var_export($result); ?>運行測試代碼,輸出結果如下
# php test/4.php -----數字降序排列----- array ( 0 => 22, 1 => 15, 2 => 3, ) -----數字升序排列----- array ( 0 => 3, 1 => 15, 2 => 22, ) -----學生成績降序排列----- array ( 0 => array ( "name" => "李四", "score" => 98, ), 1 => array ( "name" => "王五", "score" => 88, ), 2 => array ( "name" => "張三", "score" => 78, ), ) -----字符串按長度升序排列----- array ( 0 => "I", 1 => "my", 2 => "love", 3 => "country", ) -----名字按首字母升序排列----- array ( 0 => "Jack", 1 => "Michael", 2 => "Smith", 3 => "Tom", )根據上述測試代碼可見
函數類型的參數可以是匿名函數,
函數類型的參數也可以是字符串類型的函數名稱
函數類型的參數還可以是類的靜態函數的函數名
使用函數類型參數傳入有助于實現高效簡潔的代碼
三、代碼演示:引用類型的參數類型按照官網文檔的說法,PHP-CPP是支持引用類型的,而且官方文檔還給了一個swap(參數值對換)的演示代碼。我們按官網的文檔進行一下實驗。很遺憾,大家會發現對于PHP5.x這個特性是不支持的,PHP7.x系列也許支持,有條件的可以試驗一下看看。
下面是該擴展函數的C++源碼
//測試引用類型參數 void pm_swap(Php::Parameters ¶ms) { Php::Value temp = params[0]; params[0] = params[1]; params[1] = temp; }注冊該擴展函數的代碼如下
myExtension.add("pm_swap", { Php::ByRef("a", Php::Type::Numeric), Php::ByRef("b", Php::Type::Numeric) }); PHP測試代碼(test/5.php)
$a = 123; $b = 456; echo "before swap: $a = " . $a . " $b = " . $b . PHP_EOL; pm_swap($a,$b); echo "after swap: $a = " . $a . " $b = " . $b . PHP_EOL; // 如果直接輸入常量,會導致類型檢測通不過,觸發php error。 //pm_swap(10,20);運行測試代碼,輸出結果如下
before swap: $a = 123 $b = 456 after swap: $a = 123 $b = 456根據測試結果可見,$a,$b的值還是保持原樣,沒有交換過來,所以引用類型的參數在PHP5.x事實上不支持。PHP7.x是否支持還需要進一步實驗。
四、參考文獻PHP-CPP官網 - 關于函數參數
PHP-CPP官網 - 關于Lambda函數
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28637.html
摘要:前面兩節介紹了如何用編寫常用的擴展函數,擴展類。對怎么使用開發擴展應該已經很熟悉了,下面晉級學習一下關于擴展函數參數類型方面的內容。 PHP擴展是高級PHP程序員必須了解的技能之一,對于一個初入門的PHP擴展開發者,怎么才能開發一個成熟的擴展,進入PHP開發的高級領域呢?本系列開發教程將手把手帶您從入門進入高級階段。本教程系列在linux下面開發(推薦使用centos),php版本用的...
摘要:下載命令行瀏覽器下載網址和倉庫網址一樣一不帶參數,沒有返回值的擴展函數寫法函數功能打印以內的素數函數名稱如何注冊擴展函數必須在函數體中,注冊函數,以便能在中能直接調用。函數有返回值,返回值類型設置為。 PHP擴展是高級PHP程序員必須了解的技能之一,對于一個初入門的PHP擴展開發者,怎么才能開發一個成熟的擴展,進入PHP開發的高級領域呢?本系列開發教程將手把手帶您從入門進入高級階段。本...
摘要:二擴展類的普通函數支持的樣式擴展類的函數,必須按照一定的規范來寫,返回值和參數的名稱類型都是有規定。最常見的是下面種函數樣式,跟上一章的普通函數的樣式其實差不多,返回值和參數的用法也完全一樣,所以就不再多說。 PHP擴展是高級PHP程序員必須了解的技能之一,對于一個初入門的PHP擴展開發者,怎么才能開發一個成熟的擴展,進入PHP開發的高級領域呢?本系列開發教程將手把手帶您從入門進入高級...
摘要:二下載第一個擴展第一個擴展的源碼已經在上準備好了,直接用命令克隆,或者手工下載都可以。第四步確認擴展已經安裝成功使用命令可以查看目前已經安裝的所有擴展。 PHP擴展是高級PHP程序員必須了解的技能之一,對于一個初入門的PHP擴展開發者,怎么才能開發一個成熟的擴展,進入PHP開發的高級領域呢?本系列開發教程將手把手帶您從入門進入高級階段。本教程系列在linux下面開發(推薦使用cento...
閱讀 811·2023-04-25 20:18
閱讀 2092·2021-11-22 13:54
閱讀 2527·2021-09-26 09:55
閱讀 3857·2021-09-22 15:28
閱讀 2969·2021-09-03 10:34
閱讀 1710·2021-07-28 00:15
閱讀 1629·2019-08-30 14:25
閱讀 1281·2019-08-29 17:16