【PHP】21. 函數與回傳值 ( function and return value )
【PHP】21. 函數與回傳值 ( function and return value )
此文章也有影片介紹,可以搭配影片一起學習!
01. 函數與回傳值 ( function and return value) (所屬課程)
函數(function)的功用
除了PHP內建函數以外,我們也可以自行建立函數。
函數的好處是可以在程式裡被重複呼叫使用,因此我們可以更系統化的管理我們的程式碼,也可以利用更簡潔的寫法,做出更多元的計算結果。函數寫得好不好是程式碼容不容易看懂的關鍵。
新手階段通常都會把程式碼寫得很長,如果善用函數,是可以優化很多重複的部分,並且少很多註解,把程式碼整理得更精簡些。更進階的整理則還會碰到Class類別這個概念。不過目前我們還是先專注在函數上面。
基本的函數寫法如下:
// 宣告一個叫做do的函數
function doSomething ( parameter ) {
... 想要執行的內容 ...
} // <= 不需要加分號
doSomething(); // 這裡是執行的時間點
?>
宣告函數– function後面擺命名的函數名稱,小括號內可放傳入值(parameter,或叫參數),大括號內放執行代碼或回傳結果(return)。
呼叫函數– 在命名的函數名稱後放();即可呼叫宣告後的函數。
例如有一個網站標題的函數,只要呼叫它就會印出Progress Bar,我們可以這樣寫:
function printWebSiteTitle() {
echo "Progress Bar<br/>";
}
printWebSiteTitle();
?>
輸出結果:
全域變數和區域變數
因為這篇還沒有要教傳入值(parameter),所以本篇中傳入值的位置都會是空白的。
如果在函數裡想要打出數字,我們可以這樣寫:
function createLiTagByStudent(){
$number = 10;
echo "{$number}";
}
createLiTagByStudent();
?>
輸出結果:
但如果我把$number = 10;拿到外面,
$number = 10;
function createLiTagByStudent(){
echo "{$number}";
}
createLiTagByStudent();
?>
輸出結果:
它就甚麼都沒有讀到了。
這是因為PHP和JavaScript不太一樣,如果再全域直接宣告的話,函數裡面是看不到的,我們必須在function裡面再宣告 global $number,才能被讀到。
$number = 10;
function createLiTagByStudent(){
global $number;
echo "{$number}";
}
createLiTagByStudent();
?>
輸出結果:
我們知道上面的邏輯後,可以來做個練習,如果單純用for迴圈印出下面內容,
程式碼會這樣寫,
$student_list = [
["name" => "小明", "score" => "65" ],
["name" => "小美", "score" => "65" ],
["name" => "老王", "score" => "59" ],
["name" => "大華", "score" => "80" ],
];
echo "<ul>";
for ($index = 0; $index < count($student_list); $index++ ){
$student = $student_list[$index];
$name= $student["name"];
$score= $student["score"];
echo "<li>姓名:{$name} /分數:{$score}</li>";
}
echo "</ul>";
?>
那我們現在來看如何用函數和for迴圈搭配 來改寫,
$student_list = [
["name" => "小明", "score" => "65" ],
["name" => "小美", "score" => "65" ],
["name" => "老王", "score" => "59" ],
["name" => "大華", "score" => "80" ],
];
$student;
function createLiTagByStudent(){
global $student;
$name = $student["name"];
$score = $student["score"];
echo "<li>姓名:{$name} / 分數: {$score}</li>";
}
echo "<ul>";
for($index=0;$index<count($student_list);$index++){
$student=$student_list[$index];
createLiTagByStudent();
}
echo "</ul>";
?>
思路:
1. 函數的功能–印出姓名與分數
a. 建立一個函數createLiTagByStudent()
b. for迴圈可以讀到全域變數,但是函數不行。在全域裡宣告一個變數$student並在函數裡宣告global $student,這樣for迴圈就可以使用$student這個變數
c. 建立函數內變數$name和$score,讓echo可以印出來
d. 利用echo "<li>姓名:{$name} / 分數: {$score}</li>" ,將姓名和分數印出來。
2. for迴圈的功能–將清單跑出來
a. 先用<ul></ul>將li項目包住,建立一個函數createLiTagByStudent()
b. 利用$student = $student_list[$index]跑出$student_list的值
c. 在for迴圈大括號裡呼叫createLiTagByStudent()這個函數
d. for迴圈每遞增($index++)一個值,就會呼叫createLiTagByStudent()一次,直到不符合index<count($student_list)後跳出
輸出結果:
如果學過回傳值(parameter),會知道$student可以丟到函數的小括號裡,不過回傳值(parameter)有很多可以介紹的,我們會集中在下一堂中講解。
$student_list = [
["name" => "小明", "score" => "65" ],
["name" => "小美", "score" => "65" ],
["name" => "老王", "score" => "59" ],
["name" => "大華", "score" => "80" ],
];
function createLiTagByStudent($student){
global $student;
$name = $student["name"];
$score = $student["score"];
echo "<li>姓名:{$name} / 分數: {$score}</li>";
}
echo "<ul>";
for($index=0;$index<count($student_list);$index++){
$student=$student_list[$index];
createLiTagByStudent($student);
}
echo "</ul>";
?>
輸出結果:
也可以改成foreach迴圈,
$student_list = [
["name" => "小明", "score" => "65" ],
["name" => "小美", "score" => "65" ],
["name" => "老王", "score" => "59" ],
["name" => "大華", "score" => "80" ],
];
$student;
function createLiTagByStudent(){
global $student;
$name = $student["name"];
$score = $student["score"];
echo "<li>姓名:{$name} / 分數: {$score}</li>";
}
echo "<ul>";
foreach( $student_list as $stu){
$student = $stu;
createLiTagByStudent();
}
echo "</ul>";
?>
輸出結果:
我們也可以將for迴圈再包裝成另一個函數createUserList(),
$student_list = [
["name" => "小明", "score" => "65" ],
["name" => "小美", "score" => "65" ],
["name" => "老王", "score" => "59" ],
["name" => "大華", "score" => "80" ],
];
$student;
function createLiTagByStudent(){
global $student;
$name = $student["name"];
$score = $student["score"];
echo "<li>姓名:{$name} / 分數: {$score}</li>";
}
function createUserList(){
global $student;
global $student_list;
echo "<ul>";
foreach( $student_list as $stu){
$student = $stu;
createLiTagByStudent();
}
echo "</ul>";
}
createUserList();
?>
思路:
1.宣告createUserList()函數,將foreach迴圈的內容打包在createUserList()函數裡
2.在createUserList()建立global $student和global $student_list
3.呼叫createUserList()
輸出結果:
如果使用回傳值(parameter)可以將程式碼寫得更簡潔
$student_list = [
["name" => "小明", "score" => "65" ],
["name" => "小美", "score" => "65" ],
["name" => "老王", "score" => "59" ],
["name" => "大華", "score" => "80" ],
];
function createLiTagByStudent($student){
$name = $student["name"];
$score = $student["score"];
echo "<li>姓名:{$name} / 分數: {$score}</li>";
}
function createUserList($student_list){
echo "<ul>";
foreach( $student_list as $stu){
createLiTagByStudent($stu);
}
echo "</ul>";
}
createUserList($student_list);
?>
輸出結果:
像這樣的練習範例,如果有在寫現在的JavaScript前端框架也是非常常做,而且思考模式都差不多。
關於return
return代表回傳結果,會將運算的值回傳,寫在function大括號內,我們先看這個簡單的範例:
function number(){
return 5;
}
echo number();
?>
輸出結果:
那麼,我們利用本堂學到的東西,結合第8堂-算術運算,做個練習∽
[練習] 計算32483秒等於幾小時幾分幾秒?
在第8堂-算術運算裡,我們了解了小時/分鐘/秒可以用下面的方式運算,不熟悉的同學可以先回顧第8堂的內容。
$hours = intval($total_seconds / ( 60 * 60));
$minutes = floor($total_seconds / 60) % 60;
$seconds = $total_seconds % 60;
$total_seconds = 32583;
function secondsToTime(){
global $total_seconds;
$hours = intval($total_seconds / ( 60 * 60));
$minutes = floor($total_seconds / 60) % 60;
$seconds = $total_seconds % 60;
return ($hours . "小時" . $minutes . "分鐘" . $seconds . "秒");
}
echo secondsToTime();
?>
輸出結果:
思路:
1.宣告一個函數secondsToTime()
2.建立一個全域變數$total_seconds = 32583,以及在函數內建立global $total_seconds去調用它
3.建立$hours/$minutes/$seconds變數(可參照第8堂)
4.用return回傳運算結果 $hours . "小時" . $minutes . "分鐘" . $seconds . "秒"
5.用echo印出secondsToTime()裡的回傳結果值
在PHP官網裡有介紹很多return的用法,
http://php.net/manual/zh/functions.returning-values.php
如果今天有比較多值的時候,也可以用陣列的方式。
因此上面的練習也可以改成陣列的方式,這樣的好處是,如果我只想印出「小時」的時候,我可以加上echo $hours,
$total_seconds = 32583;
function secondsToTime(){
global $total_seconds;
$hours = intval($total_seconds / ( 60 * 60));
$minutes = floor($total_seconds / 60) % 60;
$seconds = $total_seconds % 60;
return array($hours . "小時" , $minutes . "分鐘" , $seconds . "秒");
}
list($hours, $minutes, $seconds) = secondsToTime();
echo $hours;
?>
輸出結果:
這樣就能指定只印出某個部份了∽
最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!