函數

在寫程式時,相同或類似邏輯的程式碼我們可能會很常使用、重複使用到很多次
函數就是將這些常用邏輯的程式碼獨立成個體,方便重複使用,以處理特定的工作
達到減少程式碼檔案大小、增加程式碼可讀性、加快開發速度的效果

舉例來說,比如說某個x的平方、y的n次方,這類的邏輯在運算上很常使用
所以PHP就內建了pow()函數來進行次方運算

<?php
    //第一個參數是底數,第二個參數是次方數
    //4的2次方
    echo pow(4,2);
    //output:16
?>

函數的命名規則

在PHP中,函數名稱的命名有一些規則,跟常數、變數的命名規則一樣
基本語法的章節已經有介紹過,這邊在幫大家複習一次

  1. 函數名稱不可以使用PHP內所定義的「關鍵字(keyword)」來命名

  2. 名稱的開頭必須為

    1. 英文字母(A-Z & a-z)

    2. 底線(_)

    後面可以接長度不限的英文字母、數字或是底線

  3. 名稱區分大小寫 Ex. Hello、hello、HELLO 是不同的名稱

  4. PHP變數在同一個的「變數作用域(Scope)」中,必須是唯一的(不能出現同樣名稱的變數)
    簡單來說,在同樣的變數作用域中,函數名稱、常數名稱、變數名稱不可以完全相同

建立函數

先看一下函數的語法格式

<?php
    //函數也可以沒有參數,那麼()內空白即可,參數也可以沒有型別跟預設值
    function 函數名稱(型別1 參數1 = 預設值1,型別2 參數2 = 預設值2,....):回傳值型別{
        //函數也可以沒有回傳值型別,就把「:回傳值型別」的部分去掉即可
        函數內容;
        return 回傳值;//函數也可以不回傳任何值,沒有回傳值那就沒有這行
    }

    //要使用某函數時,就直接使用該函數的函數名稱後面加上(),並根據順序傳入相對應的參數    
    函數名稱(參數A,參數B,參數C);
?>

我們來建立一個函數,讓購物網站的使用者能知道購買商品需要付多少運費

首先先建立一個最基本的函數

<?php
    function calShippingFee(){
        echo '超商取貨運費60元';
    }

    //-------我是分隔線-------

    calShippingFee();
    //output:超商取貨運費60元
?>

這個函數的名稱叫做calShippingFee,也就是計算運費的意思
只要呼叫這個函數,就會顯示「超商取貨運費60元」告知使用者,超商取貨的運費是60元

參數

不過我們希望除了顯示價格以外,還要幫使用者計算出含運費一共要付多少錢
所以我們把函數加上參數,讓程式碼能把使用者目前購買的金額傳遞給函數,讓函數計算完顯示出總金額

<?php
    function calShippingFee($cost){
        echo '超商取貨運費60元';
        echo '總金額:'.($cost+60);
    }

    //-------我是分隔線-------

    $want2Buy = 1050;
    calShippingFee($want2Buy);
    //output:超商取貨運費60元 總金額:1110元
?>

回傳值

不過今天程式計算完總金額之後,要存進資料庫裡面,所以需要在函數的最後一行加上回傳值(return) 讓函數將計算完成的總金額回傳.給其他程式碼去寫入資料庫
這邊要注意一下,函數只要執行到return,就代表函數執行完畢,後面的程式碼就不會繼續執行了

<?php
    function calShippingFee($cost){
        echo '超商取貨運費60元';
        $total = $cost+60;
        echo '總金額:'.$total;
        return $total;
    }

    //-------我是分隔線-------

    $want2Buy = 1050;
    $userShouldPay = calShippingFee($want2Buy);
    //output:超商取貨運費60元 總金額:1110元
?>

參數資料型別

不過這樣會有個小問題,現在calShippingFee的參數$cost雖然已經可以接收外部傳來的變數
但如果外部傳進來的資料不是整數資料型別的,傳了個字串,那麼怎麼辦呢?
所以我們要在$cost前面加上int限制能傳遞進來的資料型別只能是整數

限制參數的資料型別要PHP5以上的版本才能使用

<?php
    function calShippingFee(int $cost){
        echo '超商取貨運費60元';
        $total = $cost+60;
        echo '總金額:'.$total;
        return $total;
    }

    //-------我是分隔線-------

    $want2Buy = 1050;
    $userShouldPay = calShippingFee($want2Buy);
    //output:超商取貨運費60元 總金額:1110元
?>

這時候,如果我們傳'2kop3jf2'calShippingFee()的話,PHP就會告訴你,這不是合法的參數型別

Notice: A non well formed numeric value encountered in 檔案路徑/test.php on line 2

回傳值資料型別

甚至我們再更嚴謹一點,calShippingFee()回傳值的資料型別,我們也要確定一定是整數
否則不小心寫錯程式,回傳成字串,接收到的程式碼就可能會出錯
那要限制回傳值的資料型別,要在calShippingFee(){之間加上: 回傳值的資料型別

限制回傳值的資料型別的語法要PHP7以上的版本才能使用

<?php
    function calShippingFee(int $cost) : int{
        echo '超商取貨運費60元';
        $total = $cost+60;
        echo '總金額:'.$total;
        return $total;
    }

    //-------我是分隔線-------

    $want2Buy = 1050;
    $userShouldPay = calShippingFee($want2Buy);
    //output:超商取貨運費60元 總金額:1110元
?>

加上限制之後,如果故意把$total的值改成'string',就會出現以下的錯誤訊息

Fatal error: Uncaught TypeError: Return value of calShippingFee() must be of the type integer, string returned in 檔案路徑/test.php:12 Stack trace: #0 檔案路徑/test.php(18): calShippingFee(1050) #1 {main} thrown in 檔案路徑/test.php on line 12

參數預設值

在PHP中,函數的參數可以指定預設值,在外部程式沒有傳對應的參數給函數時,參數值就會等於預設值
參數預設值的語法是在參數後面加上= 預設值

下面這個例子就是計算x的n次方,如果外部程式沒有給n,預設就是1次方(不做計算)

<?php
    function exponential($x,$n = 1){
        //計算x的n次方,如果沒有給n,n就=1
        return $x**$n;
    }

    echo exponential(10,3); //output:1000
    echo exponential(10);   //output:10
?>

可變長度參數

假如今天我要撰寫一個函數,要將傳入的全部參數相乘,然後回傳結果
但是我無法確定會傳入的參數有幾個,那要怎麼寫?
目前我們所學的,好像只能這樣寫了...

<?php
    function calcAll_2($x1,$x2){
        return $x1*$x2;
    }

    function calcAll_3($x1,$x2,$x3){
        return $x1*$x2*$x3;
    }
    .
    .
    .
?>

可以輕易的發現,這不是一個好做法,一來寫起來太麻煩,二來今天參數不夠就要自己隨時擴充
為了解決這種問題,PHP有支援「可變長度參數(variable-lenght arguments)」
可變長度參數函數的()內不需要指定任何參數,但這樣要怎麼取得外部程式傳入的參數呢?

PHP會將外部程式傳入的參數整理成一個參數陣列,要在可變長度參數函數內取得參數陣列
必須透過下表所列的PHP函數

函數 說明
func_num_args() 取得傳入參數的個數
func_get_args() 取得傳入參數的陣列
func_get_args($i) 取得參數陣列中第$i個元素儲存的值,(陣列索引從0開始)

接下來,用「可變長度參數函數」來改寫上面的相乘函數吧~!

<?php

    function calcAll(){ //()內空著就可以了

        $result = 1;
        $argList = func_get_args();
        foreach ($argList as $value) {
            $result*=$value;
        }
        echo '一共有'.func_num_args().'個參數';
        return $result;
    }
    echo calcAll(2,3);        //output:一共有2個參數 6
    echo calcAll(2,3,4,5);    //output:一共有4個參數 120
?>

函數變數

就像是可變變數一樣,相對應的,函數也有函數變數(variable function)

直接看範例~!

<?php
    function square($x){
        //將$x平方回傳
        return $x**2;
    }

    $func = 'square';
    echo $func(10);//output:100
?>

首先我們先建立一個函數叫做square,能從外部傳入一個參數,並回傳參數的平方值
$func = 'square'就是將函數名稱儲存至變數$func
要透過$func去呼叫函數,就像是在使用函數一樣,在$func後面加上(),並且傳入對應個數的參數

這樣子寫的原理是由於PHP語言的存取機制,這邊只要先知道可以這麼做就好哩

匿名函數

匿名函數(anonymous functions)可以建立一個沒有指定名稱的函數
而因為沒有名稱,所以要用函數變數來儲存,在需要時用函數變數進行呼叫
我們把上面的範例改成匿名函數來看看

<?php
    //$square是函數變數
    $square = function($x){
        return $x**2;
    };

    echo $square(10);//output:100
?>

這邊要注意,因為function(){...};是程式敘述,不是函數,所以最後面要加上;

results matching ""

    No results matching ""