日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

Php中方法作用域,PHP 函数(下):匿名函数和作用域

發(fā)布時間:2025/3/20 php 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Php中方法作用域,PHP 函数(下):匿名函数和作用域 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

PHP 函數(shù)(下):匿名函數(shù)和作用域

由 學院君 創(chuàng)建于9個月前, 最后更新于 7個月前

版本號 #2

2282 views

1 likes

1 collects

匿名函數(shù)

從 PHP 5.3 開始,引入了對匿名函數(shù)的支持,所謂匿名函數(shù)就是在函數(shù)定義中沒有顯式聲明函數(shù)名,在 PHP 中,匿名函數(shù)也被稱作閉包函數(shù)(Closure)。

編寫匿名函數(shù)

我們在 php_learning/function 目錄下創(chuàng)建 closure.php 來存放本篇教程編寫的代碼。 以上篇教程演示的自定義函數(shù) add 為例,如果通過匿名函數(shù)進行定義,就是這樣的:

上面第一個紅色方框里面是匿名函數(shù)的定義部分,可以看到在 function 之后沒有聲明函數(shù)名,而是將整個函數(shù)賦值給了 $add 變量(不要漏掉賦值語句最后的分號),這樣,$add 就變成了函數(shù)類型,也因此,函數(shù)在 PHP 中也可以看作是一等公民(first class),可以賦值給變量進行調用,此時,如果我們試圖通過 var_dump($add) 打印 $add,結果如下:

可以看到它的類型是用于代表匿名函數(shù)的 Closure 類,并且該匿名函數(shù)支持兩個必填參數(shù) $a 和 $b。

回到 closure.php,在上述截圖的第二個紅色方框區(qū)域是匿名函數(shù)的調用部分,我們可以直接將 $add 作為一個函數(shù)名進行調用,打印結果是:

1 + 2 = 3

此外,還可以通過 PHP 內置的 call_user_func 函數(shù)調用該函數(shù),第一個參數(shù)是函數(shù)名,后面的參數(shù)是函數(shù)參數(shù)(非匿名函數(shù)亦可通過 call_user_func 函數(shù)調用):

$sum = call_user_func($add, $a, $b);

返回結果和上面的 $add($a, $b) 完全一致。

可變數(shù)量的參數(shù)列表

如果感興趣的話,看 call_user_func 函數(shù)的聲明:

function call_user_func ($function, ...$parameter)

可以看到代表參數(shù)列表的 $parameter 前面有一個 ... 前綴,其作用是標識該參數(shù)是一個可變數(shù)量的參數(shù)列表,也就是支持傳入任意多個參數(shù),從 0~N 個不等,比如我們這里傳入的就是 $a 和 $b 兩個參數(shù),如果待調用函數(shù) $function 不需要傳遞參數(shù),則 $parameter 部分留空,如果只需要傳入一個參數(shù),則傳入一個參數(shù),依此類推。

默認參數(shù)

說到這里,我們還可以為函數(shù)設置默認參數(shù),即為指定參數(shù)設置默認值,需要注意的是默認參數(shù)需要放到參數(shù)列表最后:

$add = function (int $a, int $b = 2): int {

return $a + $b;

};

這個時候,調用 $add 函數(shù)就可以不傳入第二個參數(shù)了,該參數(shù)會使用默認參數(shù)值:

$n1 = 1;

$n2 = 2;

$sum = $add($n1);

echo "$n1 + $n2 = $sum" . PHP_EOL;

當然,你可以可以傳入第二個參數(shù)覆蓋默認值:

$n1 = 1;

$n2 = 3;

$sum = $add($n1, $n2);

echo "$n1 + $n2 = $sum" . PHP_EOL;

這樣打印的結果就變成了:

1 + 3 = 4

可變函數(shù)

最后,由于 $add 是一個函數(shù)類型變量,并且 PHP 是動態(tài)類型語言,所以我們還可以像操作基本類型變量那樣將其他函數(shù)類型值賦值給 $add,這些函數(shù)類型值包括匿名函數(shù)和非匿名函數(shù),比如我們新增一個兩數(shù)相乘函數(shù) multi,然后在運行時將其賦值給 $add:

注意第二個紅色方框,我們在運行時將 multi 函數(shù)賦值給 $add,再調用 $add($n1, $n2) 則等同于調用 multi($n1, $n2),當然如果通過匿名函數(shù)定義 multi 也是可以的,對應的實現(xiàn)代碼如下:

/**

* 通過匿名函數(shù)定義兩數(shù)相加函數(shù) add

* @param int $a

* @param int $b

* @return int

*/

$add = function (int $a, int $b = 2): int {

return $a + $b;

};

/**

* 兩數(shù)相乘函數(shù) multi

* @param int $a

* @param int $b

* @return int

*/

$multi = function (int $a, int $b): int {

return $a * $b;

};

// 調用匿名函數(shù)

$n1 = 1;

$n2 = 3;

$sum = $add($n1, $n2);

echo "$n1 + $n2 = $sum" . PHP_EOL;

// 將 multi 賦值給 $add

$add = $multi;

$product = $add($n1, $n2);

echo "$n1 x $n2 = $product" . PHP_EOL;

打印結果都是一樣的:

這種在運行時動態(tài)設置函數(shù)類型值給變量的功能,在 PHP 中稱之為可變函數(shù)。

作用域

繼承父作用域變量

匿名函數(shù)(或者叫閉包函數(shù))的一個強大功能是支持在函數(shù)體中直接引用上下文變量(繼承父作用域的變量),比如在上述代碼中,我們可以這樣編寫匿名函數(shù)實現(xiàn)代碼:

$n1 = 1;

$n2 = 3;

// 計算兩數(shù)相加

$add = function () use ($n1, $n2) {

return $n1 + $n2;

};

// 計算兩數(shù)相乘

$multi = function () use ($n1, $n2){

return $n1 * $n2;

};

// 調用匿名函數(shù)

$sum = $add();

echo "$n1 + $n2 = $sum" . PHP_EOL;

$product = $multi();

echo "$n1 x $n2 = $product" . PHP_EOL;

只需要通過 use 關鍵字傳遞當前上下文中的變量,它們就可以在閉包函數(shù)體中直接使用,而不需要通過參數(shù)形式傳入,這樣一來,其他引用該文件的代碼就可以間接引用當前父作用域下的變量,如果是在類方法中定義的匿名函數(shù),則可以直接引用相應類實例的屬性,關于這一塊,學院君會在后續(xù)面向對象編程中詳細介紹。

通過 global 聲明全局變量

如果不是通過匿名函數(shù)的話,只能基于 global 關鍵字通過全局變量引用函數(shù)體外部定義的變量:

// 計算兩數(shù)相減

function sub() {

global $n1, $n2;

return $n1 - $n2;

}

global vs. 匿名函數(shù)

從父作用域中繼承變量與使用全局變量是不同的,全局變量存在于一個全局的范圍,無論當前在執(zhí)行的是哪個函數(shù),而閉包的父作用域是定義該閉包的函數(shù),不一定是調用它的函數(shù)。

我們編寫一段示例代碼來詳細解釋:

function add1($n1, $n2) {

return function () use ($n1, $n2) {

return $n1 + $n2;

};

}

function add2() {

return function () {

global $n1, $n2, $n3;

return $n1 + $n2 + $n3;

};

}

$n1 = 1;

$n2 = 3;

$n3 = 4;

$add = add1($n1, $n2);

$sum = $add();

echo "$n1 + $n2 = $sum" . PHP_EOL;

$add = add2();

$sum = $add();

echo "$n1 + $n2 + $n3 = $sum" . PHP_EOL;

在上述代碼中,add1 中定義的閉包函數(shù)通過 use 引用了父作用域下的 $n1 和 $n2 變量,對于該閉包函數(shù)來說,其作用域是 add1 函數(shù),而非調用它的位置,所以如果我們試圖在 add1 中定義的閉包函數(shù)中通過 use 引用 $n3 會報錯。

而 add2 中定義的閉包函數(shù)通過 global 關鍵字以全局變量的方式引用 $n1、$n2 和 $n3,全局變量存在于全局范圍,與調用位置無關,所以可以成功引用。

上述代碼的執(zhí)行結果是:

global 的安全隱患

但實際編碼中,盡量避免使用 global 關鍵字,因為一旦聲明了全局變量,就可以在任何位置獲取到這些全局變量,非常容易導致系統(tǒng)被攻擊,比如我們新增一個函數(shù) test,在這個函數(shù)內部就可以試圖通過 $GLOBALS 獲取對應全局變量:

function test() {

printf("n1 = %d, n2 = %d, n3 = %d\n", $GLOBALS['n1'], $GLOBALS['n2'], $GLOBALS['n3']);

}

匿名函數(shù)則有效規(guī)避了這種安全隱患。此外,匿名函數(shù)的另一個典型應用場景就是兜底處理(fallback),關于這一點,學院君將在作業(yè)項目中演示。

總結

以上是生活随笔為你收集整理的Php中方法作用域,PHP 函数(下):匿名函数和作用域的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 图片区视频区小说区 | 午夜影院免费 | 色哟哟精品一区 | 香蕉91视频 | 亚洲一区二区精品视频 | 天堂av最新网址 | 色综合中文综合网 | 精品国产综合区久久久久久 | 中文字幕亚洲欧美日韩在线不卡 | 亚洲小视频在线 | 色综合久久久久久 | 精品少妇一区二区三区免费观看 | 久久久无码一区二区三区 | 伊人影院在线视频 | 日本黄大片在线观看 | 免费黄色三级网站 | 国产九色91回来了 | 999久久久免费精品国产 | 成人黄色短视频在线观看 | av影视在线观看 | 亚洲中文字幕无码一区 | 亚洲是色 | 四虎影院污 | 黄色网页观看 | 国产精品成人久久久 | xxxx.国产 | 97精品视频在线观看 | 综合色视频 | 美女视频91| 成年人在线视频网站 | 亚洲精品视频一二三区 | 成人黄色视屏 | 日韩毛片一区二区三区 | 色四虎 | 精品人妻一区二区三区蜜桃 | 中国字幕一色哟哟 | 欧美怡红院一区二区三区 | 免费一级一片 | 91插插插插插 | 人妻熟女一区二区三区app下载 | 欧美性生交xxxxx久久久缅北 | 日韩高清一区 | 色多多视频在线观看 | av在线播放不卡 | 亚洲国产成人va在线观看天堂 | www.com污| 欧美精品性视频 | 在线播放中文字幕 | 97日日夜夜 | 国产精品男人的天堂 | 无码人妻久久一区二区三区不卡 | 一级性生活免费视频 | 久久夜视频 | 中出一区二区 | 天天综合国产 | 色欲人妻综合网 | 国产www免费| av一区二区三区免费观看 | 在线观看福利电影 | 91免费网址| 中文字幕日产av | 找av123导航| 欧美日韩国产第一页 | 亚洲成人激情在线 | 精品九九 | 国产区在线观看视频 | 亲子乱对白乱都乱了 | 国产91精品在线观看 | 国产片高清在线观看 | 娇小萝被两个黑人用半米长 | 99精品人妻无码专区在线视频区 | 欧美国产精品一区二区三区 | 午夜视频h| 黄污视频在线观看 | 正在播放老肥熟妇露脸 | 好吊视频一区二区三区四区 | 天堂av2014 | 一二三区在线观看 | 青青青草视频 | 天天操操夜夜操操 | 亚洲激情一区二区三区 | 久久久久午夜 | 五月开心播播网 | 一级欧美黄色片 | 成人天堂 | 欧美视频在线播放 | 国产午夜一级一片免费播放 | 欧美日韩在线播放三区四区 | 中文字幕乱码一二三区 | 182tv午夜| 亚洲欧美在线观看 | 欧洲精品一区二区三区久久 | 性生活视频播放 | 欧美一区二区人人喊爽 | 黄色片毛片 | 日韩在线不卡 | 久久久久久久久97 | 国产精品视频久久久久久久 | www.九九九 |