在前面幾集的章節中提到很多內建函式,ex: gettype() 和 var_dump() 等等,如果內建的功能無法滿足我現在的需求,這時就可以嘗試自己寫一個函式,由此可知函式主要分為:內建函式與自訂函式。
函式就像是一個功能,特別是需要執行相同或類似邏輯的事就可以使用,可以想像如果一直重複寫一樣的程式,一直複製貼上很沒有效率,函式就是將這些常用邏輯的程式獨立成一個個的個體,方便重複使用,達到減少程式碼檔案大小、增加可讀性與加快開發速度的功用。
建立函式
宣告方式使用 function 關鍵字,空一格接著函式名稱以及用括號包裹著的參數列表(每個參數需以逗號做分隔),最後在以左大括號做為開始,右大括號為結束,其中參數可以多個參數且回傳值不需要有也能執行。
function funcName(argument)
{
statement;
return value;//也可以不使用,通常都會加
}
回傳值
使用關鍵字 return ,可回傳任意類型像是陣列與物件等等以往提到過的資料型別,不過一次只能回傳一個值,也意味著不能以逗號做分割,會報錯。
function test($num)
{
$a = 60;
echo "num is : ".$num;
return $num, $a;
}
test(50);//會報錯
呼叫函式
頁面載入時,函式不會自動執行,函式只有在被呼叫時才會執行。
自身呼叫
函式名稱加小括號()。
<?PHP
function test($num)
{
echo "num is : ".$num;
return $num;
}
test(50);//輸出 num is : 50
?>
呼叫其他檔案 include vs require
在 PHP 引入其他檔案,就會使用到 include、require。
include 通常放在流程控制中,程式執行碰到或條件達成才會引用,
而 require 一般放在 PHP 文件的最前面,在程式執行前先導入需要的文件。
include 和 require 的差別在於,前者發生錯誤的時候會產生 Warning 但會繼續執行之後的程式碼,後者則是發生錯誤後(Error)程式停止運作。
還有一個更進階的用法 : include_once、require_once,相信看到once已經猜到是什麼意思,顧名思義會檢查該檔案在先前是否引入過,如果有就不再重複引入。
<?PHP
function test($num)
{
if($num >50){
include("test4.php");//假設test4.php不存在
}
echo "num is : ".$num;
return $num;
}
$a = test(55);
/*Warning: include(test4.php): Failed to open stream: No such file or directory in D:\xampp\htdocs\test\test2.php on line 7
Warning: include(): Failed opening 'test4.php' for inclusion (include_path='D:\xampp\php\PEAR') in D:\xampp\htdocs\test\test2.php on line 7
num is : 55*/
?>
<?PHP
require("class.php");
function test($num)
{
echo "num is :".$num;
return $num;
}
$a = test1(50);
$b = test(50)+$a;
echo "total is :".$b;
?>//輸出value is :50 num is :50 total is :100
echo "---------------------------";
//副程式 class.php
<?php
function test1(int $value){
$c = 60;
echo "value is :".$value;
return $value;
}
?>
引用參數
PHP 的引用是在變數或函式、物件等前面加上 & 符號,允許透過不同的變數名稱指向同一內容(不是另一個變數指向另一個變數),與常見的C語言指標有些差別(指標變數儲存的是變數在記憶體中的位址,透過解參考運算子 * (Dereference Operator)才能取得該位址中的內容)。常見的是引用賦值,而本篇要介紹的是引用參數。
<?PHP
function test(&$num)
{
$num++;
return $num;
}
$a = 5;
echo test($a);//輸出6
echo $a;//輸出6
?>
參數預設值
避免函式被呼叫時沒有參數值傳入,這時就可以替函式的參數加上預設值,此時參數值就會等於預設值,由於參數是由左而右傳入值,所以默認參數需放在非默認參數的右側,否則會被認定傳入參數不足,若參數預設值沒設定,表示該參數必填。
<?PHP
function test($num1, $num = 50)
{
echo "num total is : ".$num + $num1;
return $num + $num1;
}
$a = test(50);
echo $a;//輸出num total is : 100 100
?>
參數資料型別指定
單一型別
PHP 是動態(dynamic)弱型別(weak type)程式語言,由於沒有指定資料型別,就有可能導致該函式最終運行結果不如預期,像是下方的例子傳入一個資料型別位字串的數字,在嚴格模式下字串無法做運算,進而發生錯誤。
<?PHP
declare(strict_types=1);//嚴格模式
function test(int $num)
{
echo "num is : ".$num+50;
return $num;
}
$a = test("50");
echo $a;
echo $a+50;
?>
/*致命錯誤:未捕獲的 TypeError:test():參數 #1 ($num) 必須是 int 類型,但傳入的是 string 類型,
該錯誤在 D:\xampp\htdocs\test\test2.php 的第 8 行被調用,定義於 D:\xampptest\htdocs\test\23.php 的
第 3.堆疊追蹤:#0 D:\xampp\htdocs\test\test2.php(8): test('50') #1 {main} 拋出異常於D:\xampp\htdocs\test\test2.php的第3行。*/
聯合型別
單一型別進階版,允許參數可接受多個資料型別。
<?PHP
declare(strict_types=1);//嚴格模式
function test(int | string | float $num)
{
echo "num is : ".$num+50;
"<br>";
return $num;
}
$a = test("50");
echo $a;
echo $a+50;//輸出num is : 100 50 100
?>
可變參數數量
用於傳入參數數量不確定時,使用 ... 語法的參數會變成一個陣列。
<?PHP
function test(...$num)
{
$a = 0;
for($i=0;$i<count($num);$i++){
echo "data list".$i."is".$num[$i];
$a += $num[$i];
}
echo $a;
}
$a = test(1, 2, 3, 4, 5);//輸出15
?>
具名參數
具名參數(Named argument)透過 : 允許根據參數名稱傳參數給函式而不是參數位置,這樣一來就無需遵守順序且程式可讀性提升,可搭配參數預設值混合使用。
<?PHP
function test($num1, $num = 50)
{
echo "num total is : ".$num + $num1;
return $num + $num1;
}
$a = test(num1:50, num:100);
echo $a;//輸出num total is : 150 150
?>
可變函式
可變函式 (Variable functions)允許將函式名稱賦值給變數,再透過變數名稱調用,使用方式跟呼叫函式的方式一樣在變數名稱後加上小括號(),並傳入對應的參數,這種特性可用於實現回調函式 (callback)、函式表或根據條件動態執行不同函式,大大增加了程式碼的靈活性。
<?PHP
function test($num1, $num = 50)
{
echo "num total is : ".$num + $num1;
return $num + $num1;
}
$a = "test";
echo $a(50);//num total is : 100 100
?>
此外,在自訂函式中還有箭頭函式、匿名函式。
匿名函式
匿名函式(Anonymous Function)又稱為閉包函式(Closure Function),大部分的程式語言都有該功能,使用關鍵字 function 宣告,因為沒有名稱,所以需要變數來儲存,需要使用時用變數名稱加小括號呼叫,最常用作回調函式(callback)參數的值,以下方的例子來說$sum就是藉由參數傳遞到另一個函式使用的函式。
<?php
$sum = function($a, $b){return $a+$b;};
function cal($num1, $num2, $action){
echo $num1+$num2+$action(1, 2);
}
cal(3, 4, $sum)//輸出10
?>
使用 use 關鍵字可以讓匿名函式存取外部變數。
<?PHP
$c = 50;
$d = 60;
$sum = function($a, $b)use($c, $d){echo $a+$b;return $c+$d;};
$sum(1, 2);//輸出3
echo "num is : ".$sum(1, 2);//輸出3 num is : 110
?>
箭頭函式
箭頭函式(Arrow Functions)為匿名函式更簡潔的寫法,理論上也是closure的一種,與匿名函式的差別在於想存取外部變數(父層作用域變數)不需要使用關鍵子 use ,能夠自動捕獲,以及箭頭函式僅限單一表達式,不能有多行程式或陳述式。
<?PHP
$c = 50;
$d = 60;
$sum = fn($b)=> $b+$c+$d;
echo $sum(50);//輸出160
?>
❗不過閉包建議要謹慎使用,因為閉包的特性會將變數保存在記憶體中,需避免佔用多餘的記憶體,造成記憶體洩漏(memory leak)。❗
本篇文章到這裡就結束了,匿名函式跟箭頭函式真的很少遇到,也花了一些時間理解一下Callback和Closure到底是什麼,如果有術語用法錯誤的地方也希望不吝指教。
如果喜歡我的文章或覺得有用的話,歡迎動動手指點擊愛心,你/妳的支持是我最大的動力,我們下篇文章見🙌。





















