PHP 函數(shù)

碎碎念

初學(xué)PHP發(fā)現(xiàn)其作用域的概念與Javascript有很大不同诡壁,所以記下這些顷级,以免后面搞混了麦萤。

變量類別

PHP的變量分為全局變量與局部變量:

局部變量

  1. 函數(shù)體內(nèi)部聲明的變量
  2. 局部變量還分為動(dòng)態(tài)變量靜態(tài)變量
  3. 局部變量的作用域僅限于函數(shù)體內(nèi)部缕陕,外部是訪問(wèn)不到的

動(dòng)態(tài)變量

函數(shù)執(zhí)行完畢后會(huì)立即釋放味滞。

靜態(tài)變量

  1. 可以通過(guò)static關(guān)鍵字聲明
  2. 其在第一次調(diào)用函數(shù)時(shí)相當(dāng)于初始化靜態(tài)變量全封,但函數(shù)執(zhí)行完畢后靜態(tài)變量并沒(méi)有被釋放,而是被保存在靜態(tài)內(nèi)存中桃犬,當(dāng)再次調(diào)用這個(gè)函數(shù)時(shí)刹悴,首先從靜態(tài)內(nèi)存中取出變量的值繼續(xù)執(zhí)行。
function test() {
  static $j = 1;
  echo $j."<br>";
  ++$j;
}
test(); // 初次調(diào)用 1
test(); // 2
test(); // 3
test(); // 4

// 如果$j不是static聲明攒暇,則每次調(diào)用后$j變量都會(huì)被釋放土匀,會(huì)得到4個(gè)1 => 局部變量中的動(dòng)態(tài)變量
// 加上了static后,每次調(diào)用后變量并未釋放形用,而是存進(jìn)了靜態(tài)變量 => 局部變量中的靜態(tài)變量

全局變量

  1. 函數(shù)體外部聲明的變量
  2. 函數(shù)體內(nèi)部通過(guò)global關(guān)鍵字聲明的變量
$m = 3;
$n = 4;
function test() {
  var_dump($m, $n); // 此時(shí)無(wú)法獲取$m,$n
}

// 直接在函數(shù)內(nèi)部訪問(wèn)全局變量是無(wú)法得到的
// 方法1 global關(guān)鍵字
function test1() {
  global $m; // 使用全局的變量
  global $n;
  // global $m, $n; 
  var_dump($m, $n);
  $m = 7; // 此時(shí)修改的是全局變量了
  $n = 8;
}
test(); // 3 4
var_dump($m, $n); // int 7, int 8

function test1() {
  global $i, $j; // 創(chuàng)建全局變量就轧,在全局訪問(wèn)
  $i = 9;
  $j = 10;
}
test1();
var_dump($m, $n);

// 方法2 $GLOBALS超全局變量
$username="gaohang";
$age=12;
$mail="isaackao@foxmail.com";
print_r($GLOBALS);
function test2() {
  echo "用戶名是".$GLOBALS['username']."<br>";
  echo "年齡是".$GLOBALS['age']."<br>";
  echo "郵箱是".$GLOBALS['mail']."<br>";
}
test2();
// 用戶名是gaohang 年齡是12 郵箱是isaackao@foxmail.com

只能通過(guò)兩種方式,在函數(shù)體內(nèi)部訪問(wèn)全局變量田度。

  1. 通過(guò)global關(guān)鍵字
  2. 通過(guò)$GLOBALS超全局變量

傳值與傳引用

PHP與Javascript類似妒御,也有值傳遞和引用傳遞的概念,類似js傳入簡(jiǎn)單類型的值镇饺,不會(huì)改變函數(shù)外的值乎莉,傳入復(fù)雜類型則會(huì)改變其自身

默認(rèn)情況下,函數(shù)參數(shù)都是傳值的奸笤。所以在函數(shù)體內(nèi)改變參數(shù)的值也不會(huì)影響到函數(shù)外部的值惋啃。此外,可以通過(guò)再參數(shù)前面加上&符號(hào)监右,代表通過(guò)引用內(nèi)存地址傳遞參數(shù)边灭,在函數(shù)內(nèi)部對(duì)其所作的操作影響。

function test3(&$j) { // 注意&符號(hào)
  $j+=20;
  var_dump($j);
}
$k = 5;
test3($k);
var_dump($k); 
// int(25) int(25)

注意這里只有變量才能被當(dāng)作引用被傳遞健盒,如果按照test3(5)調(diào)用則無(wú)效绒瘦!

可變函數(shù)

// 可變函數(shù) 把函數(shù)名賦給一個(gè)變量 變量調(diào)用時(shí)會(huì)被當(dāng)作函數(shù)解析
$funcName = 'md5';
echo $funcName("gaohang");
echo "<br>";
echo md5("gaohang");
// 074f69168405a5e892f1d02f12896f3f
// 074f69168405a5e892f1d02f12896f3f

可變函數(shù)不能用于像echo、print扣癣、unset()惰帽、isset()、empty()搏色、include善茎、require以及類似的結(jié)構(gòu),需要封裝實(shí)現(xiàn)频轿。

自定義函數(shù)

function custom() {
    echo "this is a test function!";
}
$customFunc = 'custom';
var_dump($customFunc); // string(6) "custom"
$customFunc(); // this is a test function!
$customFunc = 'hahahah';
var_dump($customFunc); // "hahahah"
$customFunc(); // Fatal error: Uncaught Error: Call to undefined function hahahah() in xxxx

所以我們可以定義一個(gè)函數(shù)垂涯,然后將函數(shù)名賦值給變量烁焙,用變量來(lái)調(diào)用函數(shù)「福可以通過(guò)get_defined_function()來(lái)獲取所有系統(tǒng)變量(internal)和用戶自定義變量(user)骄蝇,一個(gè)關(guān)聯(lián)數(shù)組。

回調(diào)函數(shù)

回調(diào)函數(shù)說(shuō)白了就是把一個(gè)函數(shù)當(dāng)作參數(shù)傳遞進(jìn)另一個(gè)函數(shù)操骡,并在函數(shù)內(nèi)調(diào)用九火!我們可以通過(guò)可變函數(shù)的形式進(jìn)行調(diào)用,或者是call_user_func()call_user_func_array()進(jìn)行調(diào)用册招;

  • call_user_func():Calls the callback given by the first parameter and passes the remaining parameters as arguments.
<php?
function increment(&$var)
{
    $var++;
}

$a = 0;
call_user_func('increment', $a);
echo $a."\n";

// You can use this instead
call_user_func_array('increment', array(&$a)); // 注意這里參數(shù)是使用數(shù)組進(jìn)行傳遞的
echo $a."\n";
?>

匿名函數(shù)

也就是閉包岔激,臨時(shí)創(chuàng)建一個(gè)沒(méi)有指定名稱的函數(shù),最經(jīng)常用作回調(diào)函數(shù)參數(shù)的值是掰。此外虑鼎,匿名函數(shù)也可以作為變量的值來(lái)使用。

// 匿名函數(shù) 注意要加分號(hào)
$func = function() {
  return "this is a function";
};
// 通過(guò)可變函數(shù)的形式進(jìn)行調(diào)用
echo $func();

// 通過(guò)create_function創(chuàng)建匿名函數(shù)
create_function(參數(shù)列表,函數(shù)體)
$func = create_function('','"this is a function";');
$func();

// 匿名函數(shù)作為參數(shù)傳入
$array=array(1,2,3,4,5);
$res=array_map(function($var) {return $var*2;}, $array);
call_user_func(function($var) {echo "Hello {$var}";}, 'gaohang');

遞歸函數(shù)

如果函數(shù)A需要調(diào)用函數(shù)B键痛,而發(fā)現(xiàn)函數(shù)B的代碼實(shí)現(xiàn)與函數(shù)A完全相同炫彩,以此類推,此時(shí)就需要封裝成遞歸函數(shù)絮短。
直白的說(shuō)江兢,就是函數(shù)自己調(diào)用自己,以特殊條件結(jié)束執(zhí)行丁频。
比如PHP實(shí)現(xiàn)遍歷目錄杉允,目錄的復(fù)制,刪除非空目錄等等操作必須通過(guò)遞歸函數(shù)實(shí)現(xiàn)限府。無(wú)限極分類(電商網(wǎng)站的分類項(xiàng)目)也必須通過(guò)遞歸實(shí)現(xiàn)夺颤。

// 簡(jiǎn)單的遞歸
function test($i) {
  echo $i."<br>";
  --$i;
  if ($i>=0) {
    test($i);
  }
}
test(5);
5
4
3
2
1
0
image.png

使用遞歸時(shí)要注意兩個(gè)原則:

  1. 能不用遞歸就不要使用
  2. 注意遞歸的結(jié)束條件,防止無(wú)限遞歸

使用自定義函數(shù)

對(duì)于多次使用的自定義函數(shù)胁勺,我們可以使用require/require_once/inculde/include_once來(lái)引用自定義函數(shù),避免多處書寫重復(fù)的函數(shù)被独旷。

通過(guò)require/require_once包含文件不存在會(huì)產(chǎn)生一個(gè)致命錯(cuò)誤和警告署穗,且程序會(huì)終止運(yùn)行。用include則會(huì)產(chǎn)生兩個(gè)警告嵌洼,不會(huì)終止程序運(yùn)行案疲。

require與require_once的區(qū)別在于后者只會(huì)出現(xiàn)1次包含。

此外麻养,要注意代碼順序褐啡,require和include必須出現(xiàn)在調(diào)用之前,注意代碼順序鳖昌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末备畦,一起剝皮案震驚了整個(gè)濱河市低飒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌懂盐,老刑警劉巖褥赊,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異莉恼,居然都是意外死亡拌喉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門俐银,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)尿背,“玉大人,你說(shuō)我怎么就攤上這事捶惜√锩辏” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵售躁,是天一觀的道長(zhǎng)坞淮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)陪捷,這世上最難降的妖魔是什么回窘? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮市袖,結(jié)果婚禮上啡直,老公的妹妹穿的比我還像新娘。我一直安慰自己苍碟,他們只是感情好酒觅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著微峰,像睡著了一般舷丹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜓肆,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天颜凯,我揣著相機(jī)與錄音,去河邊找鬼仗扬。 笑死症概,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的早芭。 我是一名探鬼主播彼城,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了募壕?” 一聲冷哼從身側(cè)響起调炬,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎司抱,沒(méi)想到半個(gè)月后筐眷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡习柠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年匀谣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片资溃。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡武翎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溶锭,到底是詐尸還是另有隱情宝恶,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布趴捅,位于F島的核電站垫毙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拱绑。R本人自食惡果不足惜综芥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望猎拨。 院中可真熱鬧膀藐,春花似錦、人聲如沸红省。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吧恃。三九已至虾啦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痕寓,已是汗流浹背缸逃。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厂抽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓丁眼,卻偏偏與公主長(zhǎng)得像筷凤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容