PHP函數及作用域知識詳解

2022-05-25 14:01:25
本篇文章給大家帶來了關於的相關知識,其中主要介紹了關於函數以及作用域的相關問題,包括了函數命名規範、函數返回值、可變函數、匿名函數等等內容,下面一起來看一下,希望對大家有幫助。

推薦學習:《》

一、基本概念

函數:function,是一種語法結構,將實現某一個功能的程式碼塊(多行程式碼)封裝到一個結構中,從而實現程式碼的重複利用(複用)。


二、基本語法

函數有幾個對應的關鍵點:function關鍵字、函數名、引數(形參和實參)、函數體和返回值。

基本語法如下:

Function 函數名([引數]){

         //函數體,基本上所有的程式碼都可以實現,定義變數、定義常數、使用流程控制(分支、迴圈)、可以呼叫函數。
         //返回值:return 結果;
}

定義函數的目的:是為了實現程式碼的重複利用,一個功能一個函數(簡單明瞭)。

函數是在程式碼執行階段,碰到函數名字的時候才會呼叫,不是在編譯階段。函數的呼叫特點:只要系統在記憶體中能夠找到對應的函數,就可以執行(函數的呼叫可以在函數定義之前)

函數執行的記憶體分析:

  • 讀取程式碼進入到程式碼段(編譯:將程式碼變成位元組碼儲存到記憶體)
  • 根據程式碼逐行執行——編譯和執行是分開的(先編譯後執行)

三、函數命名規範

命名規範:由字母、數位和下劃線組成,但是不能以數位開頭。函數作為一種常用的結構,一般遵循以下規則:函數通常名字代表著函數的功能,而有些功能會比較複雜,可能一個單詞不足以表達,需要多個組合。

  1. 駝峰法:除了左邊第一個單詞外,後面所有的單詞首字母都大寫:showParentInfo()
  2. 劃線法:單詞之間通過下劃線連線,單詞都是小寫:show_parent_info()

四、形參和實參

形參:形式引數,不具有實際意義的引數,是在函數定義時使用的引數。

實參:實際引數,具有實際意義的引數,是在函數呼叫時使用的引數。

兩者關係:形參是實參的載體:實參在呼叫時通常是需要傳入到函數內部參與計算(運算),那麼需要在函數內部去找到實際資料所在的位置才能找到資料本身:需要實際呼叫的時候,將資料以實參的形式傳遞給形參:給形參賦值,從而使得函數內部可以用到外部資料。

<h3>函數引數形參和實參</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	//定義函數
	function jia($a,$b){  //形參可以有多個,逗號,隔開
		echo $a + $b;//函數體使用形參運算
	};
	$num = 10;//定義實參
	jia($num,2);//傳入實參,實參可以是變數、常數、運算結果等
?>

  • 在PHP中允許實參多餘形參(個數):函數內部不用而已
  • 在PHP中理論上形參個數沒有限制(實際開發不會太多)
  • 實參不能少於形參個數。


五、形參預設值

預設值:default value,指的是形參的預設值,在函數定義的時候,就給形參進行一個初始賦值:如果實際呼叫傳入的引數(實參)沒有提供,那麼形參就會使用定義時的值來進入函數內部參與運算。通常預設值是用在一些,一定會有某個資料參與,但是可能通常是某個我們知道的值。

<h3>形參預設值</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	$a = 10;//定義實參
	//定義函數
	function jia($a = 6,$b = 4){  //此時$a是實參,編譯不執行,屬於jia函數內部,跟外面的$a=10不衝突。
		echo $a + $b;//10 + 4 = 14
	};
	jia($a);//呼叫$a,有傳參就是10,$b是4,所以值就是14
	echo "<hr/>";
	echo $a;//10
?>

注意:預設值的定義是放在最右邊的(多個),不能左邊形參有預設值,但是右邊沒有函數外部定義的變數名字與函數定義的形參名字衝突(同名)是沒有任何關聯關係的;如果多個函數使用同樣的形參名字也不衝突。


六、實參參照傳遞

實參在呼叫時會將值賦值給形參,那麼實際上使用的方式就是一種簡單的值傳遞:將實參(如果是變數或者常數或者其他表示式)的結果(值)取出來賦值給形參:形參與外部實際傳入的引數本身沒有任何關聯關係:只是結果一樣。有的時候,希望在函數內部拿到的外部資料,能夠在函數內部改變,那麼就需要明確告知函數(定義時),函數才會在呼叫的時候去主動獲取外部資料的記憶體地址。以上這種定義形式引數的方式叫作參照傳值。

基本定義語法:

Function 函數名(形參1,&形參2){

//函數體

}

<h3>參照傳遞</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function xiao($x,&$y){ //定義函數xiao()
		$x = $x * $x;
		$y = $y * $y; //修改兩個形參的值
		echo $x;echo "<hr>";echo $y,"<hr>";
	};
	$x = 4;$y = 2;//定義變數
	xiao($x,$y);
	echo $x,"<hr>",$y,"<hr>";
?>

思考:兩者對比,為什麼第二個y變成了4?

參考:php——三篇夯實根基第一篇_xiaochuhe.的部落格-CSDN部落格裡面的變數參照賦值。

注意:參照傳值注意事項:在傳入實參的時候,必須傳入變數!!!


七、函數返回值(return)

返回值:return,指的是將函數實現的結果,通過return關鍵字,返回給函數外部(函數呼叫處):在PHP中所有的函數都有返回值。(如果沒有明確return使用,那麼系統預設返回NULL。

<h3>函數返回值</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function chuhe(){//定義函數
		echo __FUNCTION__;echo '<hr/>';//輸出當前函數的名稱
		echo __FILE__;echo '<hr/>';//輸出當前檔名的絕對路徑
	};
	//chuhe();echo '<hr>';
	var_dump(chuhe());

返回值作用:將計算結果返回給呼叫處,並且函數的返回值可以是任意資料型別

<h3>函數返回值——Retrun</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function jia($x,$y){
		return $x + $y;//return直接結束jia函數
		echo $x; //注意,此時echo函數不執行
	};
	$num =jia(4,5);//9
	echo $num;

  • return在函數內部存在的價值:返回當前函數的結果(當前函數執行結束)
  • return還可以在檔案中直接使用(不在函數裡面):代表檔案將結果return後面跟的內容,轉交給包含當前檔案的位置。(通常在系統組態檔中使用較多),在檔案中也代表中終止檔案後面的程式碼:return之後的內容不會執行。

八、作用域

作用域:變數(常數)能夠被存取的區域

  • 變數可以在普通程式碼中定義
  • 變數也可以在函數內部定義

作用域分類:

  1. 全域性變數
  2. 區域性變數
  3. 超全域性變數

1.全域性變數

全域性變數:就是使用者普通定義的變數(函數外部定義)

所屬全域性空間:在PHP中只允許在全域性空間使用:理論上函數內部不可方法

指令碼週期:直到指令碼執行結束(最後一行程式碼執行完)

<h3>全域性變數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	$global = "這是全域性變數!"; //定義變數
	function chuhe(){ 
		$inner = __FILE__;//區域性變數
		echo $global; //肯定是報錯的,函數內部肯定是存取不了全域性變數滴
	};
	chuhe();//呼叫函數

2.區域性變數

區域性變數:就是在函數內部定義的變數

所屬當前函數空間:在PHP中只允許在當前函數自己內部使用

函數週期:函數執行結束(函數是在棧區中開闢獨立記憶體空間執行)

<h3>區域性變數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	$global = "這是全域性變數!"; //定義變數
	function chuhe(){ 
		$inner = __FILE__;//區域性變數
		//echo $global; //肯定是報錯的,函數內部肯定是存取不了全域性變數滴
	};
	chuhe();//呼叫函數
	echo $inner;//存取區域性變數,也是報錯的

3. 超全域性變數

超全域性變數:系統定義的變數(預定義變數:$_SERVER、$_POST等)

所屬超全域性空間:沒有存取限制(函數內外都可以存取)

超全域性變數會將全域性變數自動納入到$GLOBALS裡面,而$GLOBALS沒有作用域限制,所以能夠幫助區域性去存取全域性變數:但是必須使用陣列方式。

(1)內部呼叫外部

<h3>超全域性變數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	$global = "這是全域性變數!"; //定義變數
	function chuhe(){ 
		$inner = __FILE__;//區域性變數
		echo $GLOBALS['global'];//講全域性變數納入$GLOBALS裡面
	};
	chuhe();//呼叫函數

(2)外部呼叫內部

<h3>超全域性變數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	$global = "這是全域性變數!"; //定義變數
	function chuhe(){
		global $inner; //定義變數,使用全域性變數。
		$inner = __FILE__;//區域性變數
					
	};
	chuhe();echo $inner;//呼叫函數,並存取區域性變數

4.靜態變數

靜態變數:static,是在函數內部定義的變數,使用static關鍵字修飾,用來實現跨函數共用資料的變數:函數執行結束所有區域性變數都會清空,如果重新執行一下函數,所有的區域性變數又會重新初始化。

基本語法:

Function 函數名(){

//定義變數

Static $變數名 = 值; //通常會在定義的時候就直接賦值

}

<h3>靜態變數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function xiao(){
		$a = 2;//定義變數
		static $b = 3;//定義靜態變數
		echo $a++;echo "<hr>";
		echo $b++;echo "<hr>";
	};
	xiao();//呼叫函數
	xiao();//再調一次
	xiao();//再調一次

靜態變數的作用是為了跨函數共用資料(同一個函數被多次呼叫) 。


九、可變函數

當前有一個變數所儲存到值,剛好是一個函數的名字,那麼就可以使用變數+()來充當函數名使用

<h3>可變函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function chu(){
		echo __FILE__;echo __FUNCTION__;echo __LINE__;
	}
	$xiao = "chu";//定義變數
	$xiao();//呼叫可用函數

附加思考:

<h3>可變函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function xiao($a,$b){ //假設定義系統函數
		$b = $b + 6;
		return $a($b);//chuhe(16)
	}
	function chuhe($c){
		return $c * $c * $c;  //定義一個使用者函數,求該函數的3次方
	}
	echo xiao('chuhe',10);//16*16*16
	echo "<br>","懵了吧,多想想就懂了!";
	//懵了吧,多想想就懂了!!


十、匿名函數

沒有名字的函數,變數儲存匿名函數,本質得到的是一個物件(Closure)。

<h3>函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	$xiaofeng = function(){ //定義匿名函數
		echo "我是蕭風!";
	};
	$xiaofeng();echo "<hr>";//呼叫匿名函數
	var_dump($xiaofeng);//查案變數型別及內容


十一、閉包函數

閉包:closure, 一詞來源於以下兩者的結合:要執行的程式碼塊(由於自由變數被包含在程式碼塊中,這些自由變數以及它們參照的物件沒有被釋放)和為自由變數提供繫結的計算環境(作用域)簡單理解:函數內部有一些區域性變數(要執行的程式碼塊)在函數執行之後沒有被釋放,是因為在函數內部還有對應的函數在引用(函數的內部函數:匿名函數)

<h3>閉包函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function xiaofeng(){
		$inner = __FILE__;//定義區域性變數
		#定義匿名函數
		$chuhe = function() use($inner){//用use講區域性變數保留給內部使用閉包
			echo $inner;
		};
		$chuhe();//呼叫函數
	}
	xiaofeng();

思考:函數使用完後區域性變數有沒有被釋放?

<h3>閉包函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	function xiaofeng(){
		$inner = __FILE__;//定義區域性變數
		#定義匿名函數
		$chuhe = function() use($inner){//用use講區域性變數保留給內部使用閉包
			echo $inner;
		};
		return $chuhe();//返回內部匿名函數
	}
	$closure = xiaofeng();//理論上區域性變數inner已經釋放了
	$closure();


十二、偽型別

偽型別:假型別,實際上在PHP中不存在的型別。但是通過偽型別可以幫助程式設計師去更好的檢視操作手冊從而更方便學習。

偽型別主要有兩種:在三大類八小類之外

  • Mixed:混合的,可以是多種PHP中的資料型別
  • Number:數值的,可以是任意數值型別(整形和浮點型)

十三、常用系統函數

(一)關於輸出的函數

  • print():類似於echo輸出提供的內容,本質是一種結構(不是函數),返回1,可以不需要使用括號
  • print_r():類似於var_dump,但是比var_dump簡單,不會輸出資料的型別,只會輸出值(陣列列印使用比較多)

(二)關於時間的函數

  • date():按照指定格式對對應的時間戳(從1970年格林威治時間開始計算的秒數),如果沒有指定特定的時間戳,那麼就是預設解釋當前時間戳

  • time():獲取當前時間對應的時間戳
  • microtime():獲取微秒級別的時間
  • Strtotime():按照規定格式的字串轉換成時間戳

<h3>時間函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	echo date('Y 年 m 月 d 日 H:i:s',987654321);echo "<hr>";
	echo time();echo "<hr>";
	echo microtime();echo "<hr>";
	echo strtotime(" 10 hours");

(三)關於數學的函數

  • max():指定引數中最大的值
  • min():比較兩個數中較小的值
  • rand():得到一個亂數,指定區間的隨機整數
  • mt_rand():與rand一樣,只是底層結構不一樣,效率比rand高(建議使用)
  • round():四捨五入
  • ceil():向上取整
  • floor():向下取整
  • pow():求指定數位的指定指數次結果:pow(2,8) == 2^8 == 256
  • abs():絕對值
  • sqrt():求平方根

(四)關於自定義函數的函數

  • function_exists():判斷指定的函數名字是否在記憶體中存在(幫助使用者不去使用一個不存在的函數,讓程式碼安全性更高)
  • func_get_arg():在自定義函數中去獲取指定數值對應的引數
  • func_get_args():在自定義函數中獲取所有的引數(陣列)
  • func_num_args():獲取當前自定義函數的引數數量
<h3>自定義函數</h3>
<?php
	header("Content-type:text/html;charset=gbk");
	echo "<pre>";
	function xiao($a,$b){
		print_r(func_get_arg(1));echo "<hr>";//獲取指定引數
		print_r(func_get_args());echo "<hr>";//獲取所有引數
		print_r(func_num_args());;echo "<hr>";//獲取引數數量
		
	}
	xiao(1,2);//呼叫函數
	echo "<br>";
	function_exists('xiao') && xiao(1,'2');//在呼叫函數時,判斷指定的函數名字是否在記憶體中存在(幫助使用者不去使用一個不存在的函數,讓程式碼安全性更高)

推薦學習:《》

以上就是PHP函數及作用域知識詳解的詳細內容,更多請關注TW511.COM其它相關文章!