本節講解的內容
函數的概念
函數的分類
函數的變數問題
函數的參數討論
內建函式
可變函數
匿名函數
函數的遞迴調用
前言
在PHP開發中,我們有時候會使用到大量的函數,那什麼是函數,作用又是什嗎?函數的出現可以說初次引出了封裝的概念,函數的使用可以使我們的代碼不那麼冗餘,同時函數的定義可以上我們快速的濾清思路。提高代碼的複用性,同時有利於模組化編程。
函數的概念
當我們在編程中,有這樣一個需求,需要對一個功能進行統一的整合,以便於在別的地方使用這個功能的時候不用在編寫一次(減少冗餘性),只需要調用特定的代碼就能實現。用現成的技術,我們很難實現這種需求,這時就需要使用到函數這個知識。
函數:為完成某一功能的程式指令(語句)的集合,一般一個函數最好只完成一個功能,降低代碼的耦合度。
有時候我們把函數稱之為方法,它們兩個是一個概念。
函數的分類
幾乎每種程式設計語言的函數都分為兩種:
自訂函數:
自訂函數就是我們自己根據自己的具體需求自己定義的函數,函數中的功能需要自己去實現。
自訂函數的文法規則:
function 方法名(形參列表){ 實現某種功能的代碼; return 傳回值(可以沒有傳回值,這個看需求)}
解釋:
function是一個關鍵字,如果想定義一個函數必須寫function
方法名是自己定義的,這個名字你可以隨意起,但是一般我們應該起有意義的名字,比如說這個函數要實現什麼功能的縮寫。
形參列表,當我們調用函數的時候,有時候需要傳遞給函數一些參數(也就是變數),在函數中進行操作,這個形參列表就是接受我們調用時傳過來的參數,當然可以有多個。
在PHP中函數體是需要大括弧包裹起來的,裡面寫我們的代碼。
return就是返回的意思,當我們調用函數後,有時候需要函數向我們返回一個結果,比如函數的功能是計算兩個數的和,這時候當函數通過進行加法運算後,我們可以寫return返回計算後的結果,當然有沒有傳回值需要看函數的具體功能是什麼,需不需要返回結果。
函數名的命名規則:
函數名和 PHP 中的其它標識符命名規則相同。有效函數名以字母或底線打頭,後面跟字母,數字或底線。
我們在寫函數是一般的命名規範是駝峰式命名法,也就是第二個單詞的首字母大寫。
樣本:
<?php$a = 12;$b = 6;function sum($num1,$num2){//這兩個參數就是接受我們調用時傳過來的參數 $res = $num1 + $num2; return $res; //計算完兩個數的和,返回給調用者。}$sum = sum($a,$b); //調用函數,在這裡我們會傳過去兩個參數,同時返回結果用$sum接收。echo $sum;
系統函數:
系統函數就是也是函數的一種,是系統已經封裝好的函數,系統函數有好多,不同的函數有不同的功能,我們可以根據自己的需求選取不同的函數。
在協助文檔中我們可以查詢到我們經常使用的數學函數:
abs — 絕對值
ceil — 進一法取整
decbin — 十進位轉換為二進位
dechex — 十進位轉換為十六進位
decoct — 十進位轉換為八進位
max — 找出最大值
min — 找出最小值
pow — 指數運算式
rand — 產生一個隨機整數
round — 對浮點數進行四捨五入
sqrt — 平方根
向我們有時使用的var_dump()輸出類型就是系統函數。
系統函數使用到的時候可以查看協助文檔。
函數的變數問題
全域變數和局部變數
局部變數:
在函數中我們在處理資料中,可能會定義一些變數,這些在函數中定義的變數我們稱之為局部變數,局部:顧名思義,就是在函數中使用的變數。
<?php$a = 12;$b = 6;function sum($num1,$num2){ $res = $num1 + $num2; //定義了一個變數用來儲存兩個數的和。 return $res; }$sum = sum($a,$b);echo $res; //嘗試在函數外進行輸出。echo $sum;.....結果.....Notice: Undefined variable: res in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\yusuanfu.php on line 1418
可以看到當嘗試在函數外使用函數內的變數的時候,就會報錯。
全域變數:
在上面的代碼中我們可以看到在函數外,我們定義兩個變數,
b,這種在函數外定義的變數我們稱之為全域變數。那麼全域變數能不能再函數內使用呢?
<?php$a = 12;$b = 6;function sum($num1,$num2){ $res = $num1 + $num2; echo $a;//在函數內輸出函數外的變數。 return $res; }$sum = sum($a,$b);echo $sum;.....結果.....Notice: Undefined variable: a in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\yusuanfu.php on line 10
可以看到,在函數內使用函數外的全域變數時,提示錯誤。
全域變數稱為全域,那怎麼在函數內使用呢?答案很簡單,只需要在函數中用關鍵字聲明一下就行了。
<?php$a = 12;$b = 6;function sum($num1,$num2){ $res = $num1 + $num2; global $a;//在函數內輸出函數外的變數。 echo $a; return $res; }$sum = sum($a,$b);.....結果.....12
在函數中利用global這個關鍵字進行聲明,便是需要使用全域變數$a,在這裡不得不說一下函數的調用在記憶體中的變化。
函數的調用過程大致圖:
我們的代碼都是在棧(也就是記憶體中)中啟動並執行。在棧中通過一行行的執行代碼,進行解析,在啟動並執行時候有一個存放我們資料的地區,叫資料區。當定義變數的時候,在資料區就會產生一個資料區,存放自己定義的變數。
當代碼執行到調用函數的時候,系統就會在棧中重新開闢一個棧區,並在這個新棧中執行函數(每執行一個函數就會開闢一個新棧),當在函數中建立對象的時候,就會在資料區重新定義一個地區用來存放函數中的變數。這就是在函數外不能使用函數內變數的原因。它們兩個是兩個不同的地區。
但是當我們聲明了global的時候,系統就不會在函數自己的資料區建立一個變數,而是會去函數外部的資料區,嘗試尋找用global定義的變數。但是當外部的資料區沒有我們用global定義的變數的時候,就會自動的在外部的資料區定義一個變數,使其成為全域變數。
<?php$b = 6;function sum($num1){ global $a;//在函數內通過global定義一個外部沒有的變數。 $a = 23; //在函數內進行賦值。}$sum = sum($b);echo $a; //直接使用函數內的變數。.....結果.....23
上面的$a在外部沒有定義
函數的參數討論
我們在調用函數的時候經常會去傳過去參數,而在函數上我們也定義了參數進行接受。調用函數時傳的參數稱為實際參數(實參),而函數接受的參數稱為形式參數(形參),它兩個是沒有影響的,定義時名字一樣也是可以的,但是一定要對應,不能出現調用時傳過去兩個參數,接收時一個參數。
函數的參數是允許有預設值的,也就是當我們沒有傳過去數值時,它使用預設值,但是當我們傳過去有值的時候,使用我們傳過去的值。
使用預設的:
<?php$a = 3;$b = 6;function sum($a,$b,$oper = '+'){ //形參和實參名字可以使一樣的。 if($oper == '+'){ echo $a + $b; //使用預設的加 }else if($oper == '-'){ echo $a - $b; }}$sum = sum($a,$b); //只傳進去兩個參數,運算子使用預設的情況。.....結果.....9
可以看到它並沒有報錯,同時$oper使用了預設的值+;
使用傳過去的:
<?php$a = 3;$b = 6;function sum($a,$b,$oper = '+'){ //形參和實參名字可以使一樣的。 if($oper == '+'){ echo $a + $b; }else if($oper == '-'){ echo $a - $b;//使用傳過來的加 }}$sum = sum($a,$b,'-'); //傳過去三個參數。
參數的值傳遞和引用傳遞
在函數的調用中,參數的傳遞有兩種方式:
值傳遞
當我們在調用函數,傳遞參數後在函數中進行修改,而在函數外再次使用,還是修改前的值,可以看代碼:
<?php$a = 12;function setA($a){ $a = $a * 12; //把$a的值乘以12;}setA($a);//調用函數echo $a;.....結果.....12
這種傳遞方式我們為值傳遞,預設情況下,函數參數通過值傳遞(因而即使在函數內部改變參數的值,它並不會改變函數外部的值)。如果希望允許函數修改它的參數值,必須通過引用傳遞參數。
引用參數
有時我們希望我們傳進去的值,在沒有返回的情況下,直接進行修改,這是就需要用到引用傳遞。
<?php$a = 12;function setA(&$a){ //只是在前面加了一個取地址符號。 $a = $a * 12; //把$a的值乘以12; //函數沒有傳回值}setA($a);//調用函數echo $a;.....結果.....144
在上面的代碼中只是在函數中添加了一個取地址符&,學過C語言的都知道,在C語言中使用&直接進行地址的傳遞。這就表示它在函數中的資料,會指向外邊的變數。
內建函式
內建函式: 函數內部可以申明函數,供函數內部使用,稱為內建函式
,比如某位程式員為防止他人調用,可以使用內建函式。
<?php$a = 12;$b = 6;function calculator($a,$b){ function sum($a,$b){ //在函數內部定義一個函數, return $a + $b; } function subtract($a,$b){ return $a - $b; } return sum($a,$b); // 調用自己定義的函數,把傳進來的兩個值直接傳過去。}echo calculator($a,$b); //調用函數,對返回結果直接進行輸出。.....結果.....18
其實內建函式也是可以在函數外邊使用的,就像上面的代碼, 如果我們沒有執行 calcuator, 就去調用內建函式 sum() ,就會報錯。但是如果我們執行過 calculator 則,我們也可以使用內建函式了.
<?php$a = 12;$b = 6;function calculator($a,$b){ function sum($a,$b){ //在函數內部定義一個函數, return $a + $b; } function subtract($a,$b){ return $a - $b; }}calculator($a,$b); //調用函數echo sum($a,$b); //當上面的調用過之後才能這樣調用,不然會出錯。.....結果.....18
當調用過calcuator,可以理解為記憶體中有函數內的這兩個函數,然後接著調用函數內的函數,就不會出錯。
可變函數
可變函數: PHP 支援可變函數的概念。這意味著如果一個變數名後有圓括弧,PHP 將尋找與變數的值同名的函數,並且嘗試執行它。可變函數可以用來實現包括回呼函數,函數表在內的一些用途。
看代碼可以比較清晰的理解什麼是可變函數。
<?php$a = 12;$b = 6;function add($a,$b){ $res = $a + $b; echo $res;}$fun_name = 'add';//定義一個變數,這個變數的名字是函數的函數名。$fun_name($a,$b); //把變數當成一個函數名.....結果.....18
我們在回呼函數中會使用到這種方式。
案列:
<?php$a = 6;$b = 6;function getVal($a,$b,$fun_name){ //第三個參數是一個函數的名字。 return $fun_name($a,$b); //如果一個變數名後有圓括弧,尋找與變數的值同名的函數,並且嘗試執行它。}function sum($a,$b){ //在getVal中實際上調用的就是這個函數。 return $a + $b;}echo getVal($a,$b,'sum');.....結果.....12
在上面把一個函數的名字當成變數進行傳遞。
匿名函數
匿名函數: 匿名函數,也叫閉包函數,允許臨時建立一個沒有指定名稱的函數。最經常用作回呼函數參數的值。當然,也有其它應用的情況. 簡單的理解就是 匿名函數就是沒有名字的函數。
<?php$a = 6;$b = 16;function getVal($a,$b,$fun_name){ return $fun_name($a,$b); }echo getVal($a,$b,function($a,$b){ //在傳遞的時候臨時的定義一個匿名函數,沒有名字,只有關鍵字function。 return $a + $b;});.....結果.....22
回呼函數
上面的代碼其實也是一個回呼函數。匿名函數當作回呼函數來調用。
回呼函數簡單的理解是:你調用了某個函數,而這個函數(A)內又會調用一個由你實現的另一個函數(B),那麼這個另一個函數(B)就是所謂的回呼函數,所以,一般來說,你只是不直接去調用罷了。
函數的遞迴調用
遞迴直白的說就是自己調用自己,比如函數自己調用自己,遞迴是一種演算法,它的專業說法是:
遞迴通過把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大的減少了程式的代碼量。
我們在這裡只是簡單的討論一下,不做過多的深入。
樣本:
<?phpfunction abc($n){ if($n > 2){ abc(--$n); //進行自己調用自己。 } echo '$n的值是' . $n . '<br>';}abc(4);.....結果.....2 2 3
看到結果可能一時沒有反應過來。但是如果畫圖就好理解了。
函數的遞迴需要滿足幾個條件:
- 基準情形。必須總要有某些基準條件,它無需遞迴就能解出
- 不斷推進。對於那些需要遞迴的求解的情形,每一次遞迴調用都必須要使狀況朝向一種基準情形推進
總結
上面的講解的基本上是函數的基本應用,想要熟悉的掌握函數的應用,只用多練,多想。同時,不知道有沒有發現,本節的函數都是寫在一個檔案裡面的,但是有時我們寫的函數是在另外一個檔案,這時就不能再另外一個檔案直接使用,上面的所有功能都不能使用,作為PHP程式員,你必須要知道,必然有一種方法能解決這種問題,恩,確實能解決,include和require。
以上就是PHP基礎教程五之函數的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!