首頁  >  文章  >  後端開發  >  PHP擴充開發之開發一個我們自己的數學函數庫

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

不言
不言原創
2018-04-13 16:20:171661瀏覽

這篇文章給大家分享的內容是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 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97

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

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

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

extension.add3f2a249f9aecb1d2a712d2cf71bb2afe("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 &#39;sum (1~100) = &#39; . $sum . PHP_EOL;
?>

執行以上PHP程式碼,輸出結果是

sum (1~100) = 5050

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

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

函數名稱:mm_print_pn_any

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

extension.add6d3e5fed0b3653f4cbf5967b8682fbe8("mm_print_pn_any");

函數聲明及程式碼如下。由於需要參數,函數參數需要寫成Php::Parameters ¶ms,由於沒有回傳值,回傳值類型設定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測試程式碼

<?php
echo &#39;---runing mm_print_pn_any()---&#39; . PHP_EOL;
mm_print_pn_any();

echo PHP_EOL . &#39;---runing mm_print_pn_any(\&#39;xyz\&#39;)---&#39; . PHP_EOL;
mm_print_pn_any(&#39;xyz&#39;);

echo PHP_EOL . &#39;---runing mm_print_pn_any(200)---&#39; . 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 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 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,&#39;3&#39;,&#39;5&#39;); //字符串类型可以自动转换成整形
echo &#39;sum (1,2,\&#39;3\&#39;,\&#39;5\&#39;) = &#39; . $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 &#39;sum (array(1,3,5,7)) = &#39; . $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函數開發幫助

相關推薦:

##PHP擴充開發之相關開發技術比較及介紹

PHP擴充開發之編寫第一個擴充hello world


以上是PHP擴充開發之開發一個我們自己的數學函數庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn