php自定義函數之回調函數
1).回調函數,可以配合匿名函數和變量函數實現更加優美、復雜的一種函數結構。
2).回調函數,就是在處理一個功能的時候,讓這個功能自定義能力再強一些,我准許調用這個函數的時候,還可以傳入一個函數配合、協助進行處理。
變量函數
定義: 可變函數僅僅是可變變量的一個變種、變形表達;可變函數,我們也會稱呼為變量函數;
<?php
function test(){
echo '小雞燉蘑菇';
}
$fu = 'test'; //變量$fu 調用 test()函數
$fu(); //小雞燉蘑菇
?>
回調函數
回調函數是指調用函數的時候將另一個函數作為參數傳遞到調用的函數中,而不是傳遞一個普通的變量作為參數
使用回調函數是為了可以將一段自己定義的功能傳到函數內部使用
<?php
function woziji($one,$two,$func)
{
//檢查$func是否是函數,如果不是函數停止執行本段代碼,返回false
if(!is_callable($func)){
return false;
}
//我把$one、$two相加,再把$one和$two傳入$func這個函數中處理一次
//$func是一個變量函數
echo $one + $two + $func($one,$two);
//第一次 20+10,60
//第二次 20+10,10
}
//我們定義幾個函數試試
function plusx2( $foo , $bar)
{
$result = ($foo+$bar)*2;
return $result;//60
}
function jian( $x , $y )
{
$result = $x - $y;//10
return $result;
}
//調用一下函數,woziji,向里面傳入參數試試
//'' 單引號可調用函數 - -
echo woziji(20,10,'plusx2'); //90
echo "<br />";
echo woziji(20,10,'jian'); //40
?>
回調式匿名函數
<?php
function woziji($one,$two,$func){
//檢查$func是否是函數,如果不是函數停止執行本段代碼,返回false
if(!is_callable($func)){
return false;
}
//我把$one、$two相加,再把$one和$two傳入$func這個函數中處理一次
//$func是一個變量函數
echo $one + $two + $func($one,$two);
//20+30,100
}
woziji(20,30,function( $foo , $bar){
//$foo =20,$bar=30
//$foo+$bar = 50;
$result = ($foo+$bar)*2;
return $result;
}
);
//頁面輸出150
?>
內部函數
1.內部函數,是指在函數內部又聲明了一個函數。
2.注意事項:
1).內部函數名,不能是已存在的函數名
2).假設在函數a里面定義了一個內部函數,不能定用兩次函數a。
<?php
function foo()
{
echo '我是函數foo喲,調一下我才會執行定義函數bar的過程<br />';
function bar()
{
echo '在foo函數內部有個函數叫bar函數<br />';
}
}
//現在還不能調用bar()函數,因為它還不存在
// bar();
foo();
echo "<hr />";
//現在可以調用bar()函數了,因為foo()函數的執行使得bar()函數變為已定義的函數
bar();
//再調一次foo()是會報錯的
// foo();
?>
結論:先調用bar()函數會報錯 - 可不調用bar()函數
自定義函數變量作用域
1.函數規則:
函數定義時后括號里面接的變量是形式上的參數(形參),與函數體外的變量沒有任何關系,僅僅是在函數內部執行;
函數內聲明的變量也與函數外的變量沒關系;
2.我們實際的處理情況中會遇到這樣的一個情況:
我想在函數體內定義的變量在函數體外用
我想把函數體外的變量拿到函數體內來使用
3.解決方法:使用超全局變量進行變量傳參
全局變量名 功能說明
$_COOKIE 得到會話控制中cookie傳值
$_SESSION 得到會話控制中session的值
$_FILES 得到文件上傳的結果
$_GET 得到get傳值的結果
$_POST 得到post傳值的結果
$_REQUEST 即能得到get的傳值結果,也能得到Post傳值的結果
通過$GLOBLAS來讀取外部變量
<?php
$one = 10;
function demo(){
$two = 100;
$result = $two + $GLOBALS['one']; //全局作用域傳入one
return $result;
}
//你會發現結果變成了110
echo demo();
?>
--------------------
通過$GLOBLAS,在函數內修改外部變量
<?php
$hongniu = '我是一個兵,來自老百姓';
function test(){
echo '執行了函數test喲<br />';
//調用test()函數,將通過$GLOBALS['hongniu'],把$hongniu的值改變掉
$GLOBALS['hongniu'] = '幫助別人很快樂';
}
test();
//發現輸出的值變: 幫助別人很快樂
echo $hongniu;
?>
--------------
通過$GLOBLAS,在函數內創建全局變量
<?php
function hello(){
$GLOBALS['que'] = '提神喝茶更好喲';
echo '你調了一下函數hello<br />';
//
}
hello();
echo $que; //提神喝茶更好喲
?>
--------------------------
在函數內使用global關鍵詞后面跟一個或多個變量,就把變量變為了全局變量,格式如下:
global $變量1[,變量2,....變量n]
在global后面可以跟一個或者多個變量,變量用逗號分開。
通過global調用外部變量
<?php
$a = 10;
$b = 100;
function test(){
global $a , $b;
echo $a + $b;
}
test(); //110
?>
**注意:不可在global 后寫 $變量 = 值。**
自定義函數之參數的引用
php的引用(就是在變量或者函數、對象等前面加上&符號)
在PHP 中引用的意思是:不同的名字訪問同一個變量內容。
變量的引用
//&符號代表引用
<?php
變量引用是指變量$a和$b指向到了同一個存儲位置,來存值,一個變量變化,另一個也跟着變化。
$a = 100;
$b = &$a; //$b引用變量$a的值,當$a 發生變化 $b也隨之變化
$a = 10;
echo $a.'---------'.$b;//10---------10
?>
-----------------
函數的參數引用,將形參和實參指向到同一個位置。如果形參在函數體內發生變化,那么實參的值也發生變化;
<?php
$foo = 100;
//注意:在$n前面加上了&符- -
function demo(&$n){
$n = 10; //$foo引用$n重新賦值為10
return $n + $n; //20
}
echo demo($foo).'<br />'; //20
//你會發生$foo的值變為了10
echo $foo; //10
?>
注意: 我們發現實參為$foo,在調用demo的時候,讓$foo和$n指向到了同一個存儲區域,當$n的值發生變化的時候。那么$foo的值也發生變化。
自定義遞歸函數
1.遞歸函數:函數體內調用函數自己。
2.遞歸在實際工作中主要是用在:文件和文件夾操作的時候有使用到。
3.遞歸思想:
- 代碼是從上到下執行的,所有代碼沒有exit等停止符,函數必須執行完。
- 如果函數從函數A跳至函數B后,必須把函數B執行完成再執行函數A余下的代碼。
- 遞歸函數必須要能執行完有結束條件,不然函數就會限入死循環。函數會永遠的自我執行下去。
遞歸小案例實現
<?php
$num = 10;
//調用一次函數A();
A($num);
function A( $arg ){
echo $arg; //10
//在函數A里面去,跑去執行函數B去了
B($arg); //跳至函數B中執行
echo '我們需要不斷的努力,努力到上天都為我們感動';
echo $arg.'<br />';
}
function B( $number ){
echo $number; //10
echo '俺是狗蛋,執行完了<br />';
//B函數執行完,執行A函數剩下的代碼
}
?>
輸出結果:
1010俺是狗蛋,執行完了
我們需要不斷的努力,努力到上天都為我們感動10
遞歸實現
注意:
1).第一次調用dg(),將數字$n = 2傳到dg中,先顯示出來了2
2).然后將$n - 1 $n的值為了1
3).接着判斷$n 是否大於0,肯定是大於0的,所以調用遞歸自己,再把自己執行一次。
4).而第二次在執行自己dg()的時候,而最下面的 echo '俺是狗蛋,俺還沒執行' . $n . ''; 還沒有執行到。等待執行完成后再來執行
5).$n此時等於1 ,所以顯示出來1。
6).$n把自己減了一次,$n的結果為0
7).$n大於0肯定不成立的,所以顯示了一條:"--------------"
8).而這個時候該執行:echo '俺是狗蛋,俺還沒執行' . $n . '';
9).第二次執行dg()執行完成。第一次dg()的代碼還沒執行完,將第4點中的余下代碼執行完。
<?php
$n = 2;
function dg( $n ){
echo $n.'<br />';//遞歸三次:3,2,
$n = $n - 1; //2,1
if($n > 0){
//在函數體內調用了dg自己喲
dg($n);
}else{
echo '--------------'."<br />";
}
echo '俺是狗蛋,俺還沒執行' . $n . '<br />';
}
dg(3);
?>
//第一次變量$n的值為3,執行了$n -1 ,$n為2, 輸出:俺是狗蛋,俺還沒執行2
//第二次$n=2>0 ,再一次調用自己,執行了$n -1 ,$n為1,輸出:俺是狗蛋,俺還沒執行1
//第三次$n=1>0 ,再一次調用自己,執行了$n -1 ,$n為0,輸出:俺是狗蛋,俺還沒執行0
//第四次$n=0>0 ,再一次調用自己,執行了$n -1 ,$n為0,輸出:--------------,俺是狗蛋,俺還沒執行0
自定義函數靜態變量
1.背景: 如果我想知道函數被調用了多少次怎么辦? 用靜態變量來處理;
2.靜態變量的特點是:聲明一個靜態變量,第二次調用函數的時候,靜態變量不會再初始化變量,會在原值的基礎上讀取執行。
3.有了這個特點,我們就可以實現,最開始我們的提問:函數調用次數的統計。
<?php
function demo()
{
$a = 0;
echo $a;
$a++;
}
function test()
{
static $a = 1;
echo $a;
$a++;
}
demo();
demo();
demo();
demo();
demo();
test();
test();
test();
test();
test();
//輸出結果 demo() :00000 test():12345
?>