成人精品一区二区三区中文字幕-成人精品一区二区三区-成人精品一级毛片-成人精品亚洲-日本在线视频一区二区-日本在线视频免费

導(dǎo)航首頁(yè) ? 技術(shù)教程 ? PHP基于Closure類(lèi)創(chuàng)建匿名函數(shù)的方法詳解
全站頭部文字 我要出現(xiàn)在這里
PHP基于Closure類(lèi)創(chuàng)建匿名函數(shù)的方法詳解 719 2023-12-08   

本文實(shí)例講述了PHP基于Closure類(lèi)創(chuàng)建匿名函數(shù)的方法。分享給大家供大家參考,具體如下:

Closure 類(lèi)

用于代表匿名函數(shù)的類(lèi)。

匿名函數(shù)(在 PHP 5.3 中被引入)會(huì)產(chǎn)生這個(gè)類(lèi)型的對(duì)象。在過(guò)去,這個(gè)類(lèi)被認(rèn)為是一個(gè)實(shí)現(xiàn)細(xì)節(jié),但現(xiàn)在可以依賴(lài)它做一些事情。自 PHP 5.4 起,這個(gè)類(lèi)帶有一些方法,允許在匿名函數(shù)創(chuàng)建后對(duì)其進(jìn)行更多的控制。

這個(gè)類(lèi)不能實(shí)例化,里面主要有兩個(gè)方法,都用來(lái)復(fù)制閉包,一個(gè)靜態(tài)一個(gè)動(dòng)態(tài),下面分別詳細(xì)講解下這兩個(gè)不好理解的方法。

Closure::bind

public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )

參數(shù)說(shuō)明:

closure
需要綁定的匿名函數(shù)。

newthis
需要綁定到匿名函數(shù)的對(duì)象,或者 NULL 創(chuàng)建未綁定的閉包。

newscope
想要綁定給閉包的類(lèi)作用域,或者 'static' 表示不改變。如果傳入一個(gè)對(duì)象,則使用這個(gè)對(duì)象的類(lèi)型名。 類(lèi)作用域用來(lái)決定在閉包中 $this 對(duì)象的 私有、保護(hù)方法 的可見(jiàn)性。

The class scope to which associate the closure is to be associated, or 'static' to keep the current one. If an object is given, the type of the object will be used instead. This determines the visibility of protected and private methods of the bound object.

上面是該方法的定義,第一個(gè)參數(shù)很好理解,就是一個(gè)閉包函數(shù);第二個(gè)參數(shù)就不太好理解,如果要復(fù)制的閉包中包含$this,這個(gè)對(duì)象就表示這個(gè)$this,閉包函數(shù)里面對(duì)這個(gè)對(duì)象的修改在調(diào)用結(jié)束之后也會(huì)保持一致,比如修改了一個(gè)屬性;第三個(gè)參數(shù)就不太好理解了,看官方的說(shuō)明也是云里霧里的,默認(rèn)參數(shù)情況下,調(diào)用$this->訪問(wèn)object $newthis中的屬性函數(shù)的時(shí)候,會(huì)有限制,只能訪問(wèn)public屬性的函數(shù),如果想訪問(wèn)protected/private屬性,就要設(shè)置為對(duì)應(yīng)的類(lèi)名/類(lèi)實(shí)例,就要像在類(lèi)里面一樣,要訪問(wèn)那個(gè)類(lèi)的保護(hù)/私有屬性函數(shù)。

例子

<?php
class T {
  private function show()
  {
    echo "我是T里面的私有函數(shù):shown";
  }
  protected function who()
  {
    echo "我是T里面的保護(hù)函數(shù):whon";
  }
  public function name()
  {
    echo "我是T里面的公共函數(shù):namen";
  }
}
$test = new T();
$func = Closure::bind(function(){
  $this->who();
  $this->name();
  $this->show();
}, $test);
$func();

上面的代碼會(huì)報(bào)錯(cuò)Fatal error: Uncaught Error: Call to protected method T::who() from context 'Closure'。

加上bind第三個(gè)參數(shù)為t::class或者new T(),會(huì)正常輸出每一個(gè)結(jié)果。

我是T里面的保護(hù)函數(shù):who
我是T里面的公共函數(shù):name
我是T里面的私有函數(shù):show

當(dāng)然了,閉包也可以傳遞參數(shù)

$test = new StdClass();
var_dump($test);
$func = Closure::bind(function($obj){
  $obj->name = "燕睿濤";
}, null);
$func($test);
var_dump($test);

上面的程序跟匿名函數(shù)一樣,啥對(duì)象也沒(méi)有依賴(lài),上面的程序會(huì)輸出:

object(stdClass)#1 (0) {
}
object(stdClass)#1 (1) {
 ["name"]=>
 string(9) "燕睿濤"
}

另外還有個(gè)特別要說(shuō)明的例子

<?php
class T {
  private function show()
  {
    echo "我是T里面的私有函數(shù):shown";
  }
  protected function who()
  {
    echo "我是T里面的保護(hù)函數(shù):whon";
  }
  public function name()
  {
    echo "我是T里面的公共函數(shù):namen";
  }
}
$func = Closure::bind(function ($obj) {
  $obj->show();
}, null);
$test = new T();
$func($test);

上面的情況會(huì)輸出什么呢,沒(méi)錯(cuò),會(huì)報(bào)錯(cuò),提示訪問(wèn)不了私有屬性show,這個(gè)時(shí)候,加上第三個(gè)參數(shù)就可以了,看了第三個(gè)參數(shù)不光影響$this的作用域,也可以影響參數(shù)的作用域。

Closure::bindTo

bindTo和bind功能類(lèi)似,這里只是另外一種形式,都是復(fù)制當(dāng)前閉包對(duì)象,綁定指定的$this對(duì)象和類(lèi)作用域。,參數(shù)比bind少了第一個(gè),后面兩個(gè)一樣,當(dāng)然還有一個(gè)區(qū)別就是bindTo不是靜態(tài)方法,是閉包才會(huì)存在的一個(gè)屬性方法。

例子

<?php
class T {
  private function show()
  {
    echo "我是T里面的私有函數(shù):shown";
  }
  protected function who()
  {
    echo "我是T里面的保護(hù)函數(shù):whon";
  }
  public function name()
  {
    echo "我是T里面的公共函數(shù):namen";
  }
}
$func = function () {
  $this->show();
  $this->who();
  $this->name();
};
$funcNew = $func->bindTo(new T(), T::class);
$funcNew();

上面函數(shù)的輸出和bind的類(lèi)似

我是T里面的私有函數(shù):show
我是T里面的保護(hù)函數(shù):who
我是T里面的公共函數(shù):name

一個(gè)trick

這個(gè)函數(shù)是在看composer生成的自動(dòng)加載源碼的時(shí)候碰到的,在composer中用的比較特別,下面是截取部分composer中的代碼

// 文件autoload_real.php
call_user_func(ComposerAutoloadComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader));
// 文件autoload_static.php
public static function getInitializer(ClassLoader $loader)
{
  return Closure::bind(function () use ($loader) {
    $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;
    $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;
    $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;
    $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;
  }, null, ClassLoader::class);
}

上面的代碼比較奇特,在call_user_func中,第一感覺(jué)是傳錯(cuò)參數(shù)了,其實(shí)不然,這里調(diào)用了一個(gè)函數(shù),這個(gè)函數(shù)會(huì)返回一個(gè)Closure對(duì)象,也就是一個(gè)匿名函數(shù),最終傳入的參數(shù)還是一個(gè)callable類(lèi)型。再看看這個(gè)返回的閉包,里面使用了use,這是連接閉包和外部變量的橋梁。

至于這里為什么普通傳參數(shù)就可以,是因?yàn)閜hp5里面,對(duì)象形參和實(shí)參數(shù)指向相同的對(duì)象,函數(shù)里面對(duì)對(duì)象的修改會(huì)反映到對(duì)象外面。

所以,上面這么做是沒(méi)問(wèn)題的,還有另外一種形式也可以

call_user_func(ComposerAutoloadComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer(), $loader);
public static function getInitializer()
{
  return Closure::bind(function ($loader) {
    $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;
    $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;
    $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;
    $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;
  }, null, ClassLoader::class);
}

更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《php常用函數(shù)與技巧總結(jié)》、《php字符串(string)用法總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《PHP數(shù)據(jù)結(jié)構(gòu)與算法教程》及《php程序設(shè)計(jì)算法總結(jié)》

希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。


主站蜘蛛池模板: 零食加盟店10大品牌| 花宵道中1| 电影画皮3免费| 戴夫·巴蒂斯塔| 荒山之夜| 笔仙2大尺度床戏| 《密爱》| 果宝特攻5 2030| 黄鸟电影| 韩国我的养父电影免费观看| 少年的奇幻漂流记| nina hartley| 假男假女| 不可饶恕 电影| 速度与激情18| 84年社保要交15年还是20年| 演员任贤齐简历| 刘慧茹| 混凝土结构设计规范gb50010-2020 | 17岁韩国电影完整版观看免费| 陕09j01图集| 电影五十度黑| 一夜风流| 大场久美子| 亚洲人视频在线观看| dota2反和谐| 《月夜》电影| 辩论赛作文| 浪人电影在线观看完整版免费| 漂亮的女邻居5伦理| 康巴卫视直播| 出埃及记电影| 韩国电影《表妹》| 美网直播| 燃冬海报| 不离不弃 电视剧| 变形金刚1免费完整版在线观看 | 赵煊| 欧卡2mod| 雷霆出击电视剧全集在线观看| 工作细胞 2018|

?。?!站長(zhǎng)長(zhǎng)期在線接?。。?/p>

網(wǎng)站、小程序:定制開(kāi)發(fā)/二次開(kāi)發(fā)/仿制開(kāi)發(fā)等

各種疑難雜癥解決/定制接口/定制采集等

站長(zhǎng)微信:lxwl520520

站長(zhǎng)QQ:1737366103