進度條

【PHP】21. 函數與回傳值 ( function and return value )

【PHP】21. 函數與回傳值 ( function and return value )

作者: 進度條編輯群 更新日期:

此文章也有影片介紹,可以搭配影片一起學習!

01. 函數與回傳值 ( function and return value) (所屬課程)

02. 函數與回傳值 ( function and return value) (所屬課程)


以下正式開始文章


函數(function)的功用

除了PHP內建函數以外,我們也可以自行建立函數。

 

函數的好處是可以在程式裡被重複呼叫使用,因此我們可以更系統化的管理我們的程式碼,也可以利用更簡潔的寫法,做出更多元的計算結果。函數寫得好不好是程式碼容不容易看懂的關鍵。

 

新手階段通常都會把程式碼寫得很長,如果善用函數,是可以優化很多重複的部分,並且少很多註解,把程式碼整理得更精簡些。更進階的整理則還會碰到Class類別這個概念。不過目前我們還是先專注在函數上面。

 

基本的函數寫法如下:

 

<?php

 // 宣告一個叫做do的函數
 function doSomething ( parameter ) {
 
      ...  想要執行的內容 ...
 
 }  // <= 不需要加分號

 doSomething();    // 這裡是執行的時間點
?>


 

宣告函數– function後面擺命名的函數名稱,小括號內可放傳入值(parameter,或叫參數),大括號內放執行代碼或回傳結果(return)。
 

呼叫函數– 在命名的函數名稱後放();即可呼叫宣告後的函數。


例如有一個網站標題的函數,只要呼叫它就會印出Progress Bar,我們可以這樣寫:
 

<?php

  function printWebSiteTitle() {
    echo "Progress Bar<br/>";
  }

  printWebSiteTitle(); 
?>    



輸出結果:
 

Progress Bar    

 

 

 


全域變數和區域變數

因為這篇還沒有要教傳入值(parameter),所以本篇中傳入值的位置都會是空白的。

 

如果在函數裡想要打出數字,我們可以這樣寫:

 

<?php
function createLiTagByStudent(){
  $number = 10;
  echo "{$number}";
}

createLiTagByStudent();
?>    


輸出結果:

10    

 


但如果我把$number = 10;拿到外面,

 

<?php
$number = 10;

function createLiTagByStudent(){
  echo "{$number}";
}
createLiTagByStudent();
?>    


輸出結果:

 

它就甚麼都沒有讀到了。

 

這是因為PHP和JavaScript不太一樣,如果再全域直接宣告的話,函數裡面是看不到的,我們必須在function裡面再宣告 global $number,才能被讀到。

 

<?php

$number = 10;

function createLiTagByStudent(){
  global $number;
  echo "{$number}";
}

createLiTagByStudent();
?>    

 


輸出結果:

 

10    

 


我們知道上面的邏輯後,可以來做個練習,如果單純用for迴圈印出下面內容,

 

 

 

程式碼會這樣寫,

<?php

$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迴圈搭配 來改寫,

<?php
  $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)有很多可以介紹的,我們會集中在下一堂中講解。

 

<?php

  $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迴圈,

<?php
  $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(),    

<?php
  $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 $studentglobal $student_list

3.呼叫createUserList()

輸出結果:

 

 

 

如果使用回傳值(parameter)可以將程式碼寫得更簡潔

 

<?php
  $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大括號內,我們先看這個簡單的範例:
 

<?php
function number(){
  return 5;
}

echo number();

?>    


輸出結果:

5    




那麼,我們利用本堂學到的東西,結合第8堂-算術運算,做個練習∽


[練習]  計算32483秒等於幾小時幾分幾秒?

在第8堂-算術運算裡,我們了解了小時/分鐘/秒可以用下面的方式運算,不熟悉的同學可以先回顧第8堂的內容。

$hours = intval($total_seconds / ( 60 * 60));

$minutes = floor($total_seconds / 60) % 60;

$seconds = $total_seconds % 60;

 

<?php
 
  $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();
?>    


輸出結果:

9小時3分鐘3秒    


思路:

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

 

<?php

  $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;


?>    


輸出結果:

9小時    


這樣就能指定只印出某個部份了∽


 

 


最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!

Small logo

進度條編輯群

進度條編輯團隊