PHP擴充開發之開發一個我們自己的數學函數庫

來源:互聯網
上載者:User
本篇文章給大家分享的內容是PHP擴充開發之開發一個我們自己的數學函數庫 ,有著一定的參考價值,有需要的朋友可以參考一下

PHP擴充是進階PHP程式員必須瞭解的技能之一,對於一個初入門的PHP擴充開發人員,怎麼才能開發一個成熟的擴充,進入PHP開發的進階領域呢?本系列開發教程將手把手帶您從入門進入進階階段。
本教程系列在linux下面開發(推薦使用centos),php版本用的是5.6,並假設您有一定的linux操作經驗和c/c++基礎。
有問題需要溝通的朋友請加QQ技術交流群32550793和我溝通。

上一章示範了一個hello world擴充,大家基本瞭解了用PHP-CPP開發的擴充的C++源碼的基本樣式。下面一起開發一個簡單的數學運算庫(mymath)來熟悉如何匯出各種介面函數。
mymath數學庫的代碼已放在github上,可以直接git下載或者瀏覽器開啟網頁下載源碼。

git下載命令列

git clone https://github.com/elvisszhang/phpcpp_mymath.git

瀏覽器下載網址和倉庫網址一樣:https://github.com/elvisszhan...

一、不帶參數,沒有傳回值的擴充函數寫法

函數功能:列印100以內的素數

函數名稱:mm_print_pn_100

如何註冊擴充函數

必須在get_module函數體中,註冊函數 mm_print_pn_100,以便能在php中能直接調用。

PHPCPP_EXPORT void *get_module() {        // 必須是static類型,因為擴充項物件需要在PHP進程內常駐記憶體        static Php::Extension extension("mymath", "1.0.0");                //這裡可以添加你要暴露給PHP調用的函數        extension.add<mm_print_pn_100>("mm_print_pn_100");                // 返回擴充項物件指標        return extension;}

函式宣告及代碼如下。
函數不需要參數,函數的參數列表裡面什麼也不用放,空著就行。函數不需要傳回值,傳回值類型設定為void。

//列印100以內的素數void mm_print_pn_100(){    int x = 2;    int y = 1;    int line = 0;    while (x <= 100){        int z = x - y; //z隨y遞減1        int a = x%z; //取餘數        if (a == 0) { //如果x被z整除            if (z == 1) {//如果z為1(x是質數)                Php::out << x << " ";//輸出x                line ++;//每行輸出的數的數量加1             }            x ++; //x加1            y = 1;//y還原        }        else {//如果沒有被整除            y ++;//y加1,下一次迴圈中z減1        }        if (line == 10) {//每輸出10個數             Php::out << std::endl;//輸出一個換行                    line = 0;//還原line        }    }    if (line != 0) //最後一行輸出換行        Php::out << std::endl;    Php::out.flush();}

PHP測試代碼

<?php//列印100以內的素數mm_print_pn_100();

運行以上PHP代碼,輸出結果是

2 3 5 7 11 13 17 19 23 2931 37 41 43 47 53 59 61 67 7173 79 83 89 97

二、不帶參數,有傳回值的擴充函數寫法

函數功能:計算1、2、3、...、100的和
函數名稱:mm_sum_1_100

註冊函數 mm_sum_1_100,註冊方式同上一節

extension.add<mm_sum_1_100>("mm_sum_1_100");

函式宣告及代碼如下。
函數不需要參數,函數參數列表設定為空白就可以。
函數有傳回值,傳回值類型設定為 Php::Value。由於Php::value 重載了建構函式和operator = 運算子,常見資料類型(整形,字串,浮點數,數組等)可以直接返回。

//擷取1-100的和Php::Value mm_sum_1_100(){    int sum = 0;    int i;    for(i=1;i<=100;i++){        sum += i;    }    return sum; //可以直接返回sum值,自動產生 Php::value 類型}

PHP測試代碼:

<?php$sum = mm_sum_1_100();echo 'sum (1~100) = ' . $sum . PHP_EOL;?>

運行以上PHP代碼,輸出結果是

sum (1~100) = 5050

三、帶有參數,沒有傳回值的擴充函數寫法

函數功能:計算任意給定整數,列印該整數以內的所有素數

函數名稱:mm_print_pn_any

註冊函數 mm_print_pn_any,註冊方式同上一節

extension.add<mm_print_pn_any>("mm_print_pn_any");

函式宣告及代碼如下。由於需要參數,函數參數需要寫成Php::Parameters &params,由於沒有傳回值,傳回值類型設定void。
另外需要檢測參數是否輸入,參數的類型也需要檢測是不是整形。不檢測直接用的話,代碼容易出異常。

//任意給定一個整數,列印出小於等於該整數的所有素數void mm_print_pn_any(Php::Parameters &params){    //檢查必須輸入一個參數    if(params.size() == 0){        Php::out << "error: need a parameter " << std::endl;        return;    }    //檢查參數必須是整形    if( params[0].type() != Php::Type::Numeric){        Php::out << "error: parameter must be numeric" << std::endl;        return;    }    //檢查數字必須大於1    int number = params[0];    if(number <= 1){        Php::out << "error: parameter must be larger than 1" << std::endl;        return;    }    //檢查參數必須大於0    int x = 2;    int y = 1;    int line = 0;    while (x <= number){        int z = x - y; //z隨y遞減1        int a = x%z; //取餘數        if (a == 0) { //如果x被z整除            if (z == 1) {//如果z為1(x是質數)                Php::out << x << " ";//輸出x                line ++;//每行輸出的數的數量加1             }            x ++; //x加1            y = 1;//y還原        }        else {//如果沒有被整除            y ++;//y加1,下一次迴圈中z減1        }        if (line == 10) {//每輸出10個數            Php::out << std::endl;//輸出一個換行                    line = 0;//還原line        }    }    if (line != 0) //最後一行輸出換行        Php::out << std::endl;    Php::out.flush();    }

PHP測試代碼

<?phpecho '---runing mm_print_pn_any()---' . PHP_EOL;mm_print_pn_any();echo PHP_EOL . '---runing mm_print_pn_any(\'xyz\')---' . PHP_EOL;mm_print_pn_any('xyz');echo PHP_EOL . '---runing mm_print_pn_any(200)---' . PHP_EOL;mm_print_pn_any(200);?>

運行以上PHP代碼,輸出結果是

---runing mm_print_pn_any()---error: need a parameter---runing mm_print_pn_any('xyz')---error: parameter must be numeric---runing mm_print_pn_any(200)---2 3 5 7 11 13 17 19 23 2931 37 41 43 47 53 59 61 67 7173 79 83 89 97 101 103 107 109 113127 131 137 139 149 151 157 163 167 173179 181 191 193 197 199

四、標量型參數,有傳回值的擴充函數寫法

函數功能:給定一系列參數,計算其總和

函數名稱:mm_sum_all

註冊擴充函數 mm_sum_all,註冊方式同上一節

extension.add<mm_sum_all>("mm_sum_all");

函式宣告及代碼如下。

//擷取所有參數的和Php::Value mm_sum_all(Php::Parameters &params){    int sum = 0;    for (auto &param : params){        //字串類型可以自動轉換成整形        sum += param;    }    return sum;}

PHP測試代碼

<?php$sum = mm_sum_all(1,2,'3','5'); //字串類型可以自動轉換成整形echo 'sum (1,2,\'3\',\'5\') = ' . $sum . PHP_EOL;?>

測試輸出結果:

sum (1,2,'3','5') = 11

五、數組型參數,有傳回值的擴充函數寫法

函數功能:給定一個數群組類型的參數,計算數組全部元素的總和

函數名稱:mm_sum_array

註冊函數 mm_sum_array ,註冊方式同第一節

函式宣告及代碼如下。

//擷取所有數組各元素的和Php::Value mm_sum_array(Php::Parameters &params){    //沒有給定參數,返回0    if(params.size() == 0){        return 0;    }    //參數類型不是數組,轉成整形返回    if( params[0].type() != Php::Type::Array){        return (int)params[0];    }    //數組中的元素逐個相加    int sum = 0;    Php::Value array = params[0];    int size = array.size();    int i;    for(i=0;i<size;i++){        sum += array.get(i);    }    return sum;}

PHP測試代碼

<?php$nums = array(1,3,5,7);$sum = mm_sum_array($nums);echo 'sum (array(1,3,5,7)) = ' . $sum . PHP_EOL;?>

測試輸出結果:

sum (array(1,3,5,7)) = 16

六、傳回值類型是數組的擴充函數寫法

上面函數的傳回值都是標量類型,數組是PHP特別常用的類型,如果想返回一個數群組類型,可以使用c++的std::vector,PHP-CPP會貼心的把它自動轉換成PHP認識的數群組類型。

我們現在的示範函數功能是“返回30以內的所有素數的數組”。擴充裡面註冊函數的方式同第一節。

函式宣告及代碼如下。

//擷取30以內的所有素數Php::Value mm_get_pn_30(){    std::vector<int> pn;    int x = 2;    int y = 1;    while (x <= 30){        int z = x - y; //z隨y遞減1        int a = x%z; //取餘數        if (a == 0) { //如果x被z整除            if (z == 1) {//如果z為1(x是質數)                pn.push_back(x); //放數組中去            }            x ++; //x加1            y = 1;//y還原        }        else {//如果沒有被整除            y ++;//y加1,下一次迴圈中z減1        }    }        return pn;}

PHP測試代碼

<?php$pn = mm_get_pn_30();var_dump($pn);?>

測試輸出結果:

array(10) {  [0]=>  int(2)  [1]=>  int(3)  [2]=>  int(5)  [3]=>  int(7)  [4]=>  int(11)  [5]=>  int(13)  [6]=>  int(17)  [7]=>  int(19)  [8]=>  int(23)  [9]=>  int(29)}

七、參考文獻

c++質數判定及輸出質數表
PHP-CPP函數開發協助

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.