• [放鞭炮][福]玉竹斑斑节日快乐![福][放鞭炮] 2019-05-23
  • 三狮军团首秀 只有两千多球迷观战 2019-05-19
  • 人民网2017呼和浩特徒步迎新活动--内蒙古频道--人民网 2019-05-19
  • 【品牌资讯】环球网斩获“全国行业新闻网站传播力2017年6月榜”多项冠军 2019-05-15
  • 深化对经济工作主线的认识 从供需关系看供给侧结构性改革 2019-05-15
  • 格拉斯哥艺术学院起火 4年前曾遭火灾仍在整修 2019-05-14
  • 回复@地瓜干17世:猪临死才会嚎叫呢~ 2019-05-14
  • 婺源古村溪中发现鹰嘴龟 2019-05-08
  • 编辑评测:高夫净源控油平衡露 极速补水长效控油 2019-05-08
  • 四部门发文规范特色小镇建设防止“新瓶装旧酒” 2019-05-02
  • 【地球的盛会文明的聚会艺术的盛宴四海一家足球为人类和平幸福而荣耀!!!普京是当今人类世界最优秀的一代伟人俄罗斯赢啦!!!】 2019-04-29
  • 学习新思想,千万师生同上一堂课 2019-04-28
  • 你这种个体户都干不了的老蚕也配谈计划?真是笑死人不偿命哦? 2019-04-23
  • 感人!的哥带着患病父亲出车 孝心感动乘客 2019-04-23
  • 图解:习近平在纪念马克思诞辰200周年大会上讲话的16个金句 2019-04-16
  • 十一选五玩法中奖规则:浅谈PHP匿名函数和闭包

    山西体彩11选5直选遗漏 www.caxru.com  更新时间:2019年03月08日 15:14:27   作者:itbsl   我要评论

    这篇文章主要介绍了PHP匿名函数和闭包,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    概述

    闭包和匿名函数在PHP 5.3.0中引入,这两个特性非常有用,每个PHP开发者都应该掌握。

    匿名函数其实就是没有名称的函数,匿名函数可以赋值给变量,还能像其他任何PHP函数对象那样传递。不过匿名函数仍然是函数,因此可以调用,还可以传入参数,适合作为函数或方法的回调。

    闭包是指在创建时封装周围状态的函数,即使闭包所在的环境的不存在了,闭包中封装的状态依然存在。

    创建匿名函数

    创建匿名函数很简单:

    //将匿名函数赋给一个变量,通过变量名+()的形式来调用
    $greet = function () {
     return "Hello World";
    };
    
    echo $greet();

    结果打印:

    Hello World

    匿名函数和普通的PHP函数很像:常用的句法相同,也接受参数,而且能返回值。不过闭包没有函数名。

    注:我们之所以能调用$greet变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()魔术方法,只要变量名后有(),PHP就会查找并调用__invoke方法。

    我们通常把匿名函数当做函数或方法的回调使用,事实上,很多PHP函数都会用到匿名函数,比如array_mappreg_replace_callback,这是使用PHP匿名函数的绝佳时机。记住,闭包和其他值一样,可以作为参数传入其他PHP函数:

    $numberPlusOne = array_map(function ($number) {
     return $number += 1;
    }, [1, 2, 3]);
    
    print_r($numberPlusOne);

    在匿名函数出现之前,要实现这样的功能,PHP开发者只能单独创建具名函数,然后使用名称引用这个函数:

    function incrementNumber ($number) {
     return $number += 1;
    }
    
    $numberPlusOne = array_map(‘incrementNumber', [1, 2, 3]);
    print_r($numberPlusOne);

    这样做把回调的实现和使用场所隔离开了,而且使用闭包实现代码更加简洁。

    创建闭包

    包含自由变量的函数与为所有这些自由变量提供了变量绑定的环境一起,被称为闭包。

    function makeHelloWorld($name) { 
     $i = 0;
     return function()use($name, &$i){
      echo $name.$i. ' <br>';
      $i++;
     };
    
    }
    $hello1 = makeHelloWorld("itbsl");
    $hello2 = makeHelloWorld("kevin");
    $hello1();
    $hello1();
    $hello1();
    $hello2();

    打印结果:

    itbsl0
    itbsl1
    itbsl2
    kevin0

    从父作用域继承变量

    在PHP中必须手动调用闭包对象的bindTo方法或使用use关键字把父作用域的变量及状态附加到PHP闭包中。而实际应用中,又以使用use关键字实现居多。

    use关键字

    实际上,Laravel框架中也大量使用了闭包,最常见的比如路由定义:

    Route::group(['domain' => '{account}.myapp.com'], function () {
     Route::get('user/{id}', function ($account, $id) {
      //
     });
    });

    这里面的两个function都是匿名函数。而从父作用域继承变量的使用场景在Laravel底层源码中也是俯拾即是,比如Model.php(Illuminate\Database\Eloquent)的saveOrFail方法:

    该方法的作用是使用事务将模型数据保存到数据库,这里面我们使用匿名函数返回保存状态,同时使用use关键字将父作用域的$options传递给该闭包以便其能够访问这个数据。

    此外,还支持传递多个父作用域变量到匿名函数,比如还是在Model类中的forceFill方法:

    多个变量以逗号分隔即可。

    bindTo方法

    我们在前面已经提到,闭包是一个对象,所以我们可以在闭包中使用$this关键字获取闭包的内部状态,闭包对象的默认状态没什么用,需要注意的是其中的__invoke魔术方法和bindTo方法。

    __invoke的作用前面已经说过,当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

    接下来我们来看看bindTo方法,通过该方法,我们可以把闭包的内部状态绑定到其他对象上。这里bindTo方法的第二个参数显得尤为重要,其作用是指定绑定闭包的那个对象所属的PHP类,这样,闭包就可以在其他地方访问邦定闭包的对象中受?;ず退接械某稍北淞?。

    你会发现,PHP框架经常使用bindTo方法把路由URL映射到匿名回调函数上,框架会把匿名回调函数绑定到应用对象上,这样在匿名函数中就可以使用$this关键字引用重要的应用对象:

    class App {
     protected $routes = [];
     protected $responseStatus = '200 OK';
     protected $responseContentType = 'text/html';
     protected $responseBody = 'Laravel学院';
    
     public function addRoute($routePath, $routeCallback) {
      $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);
     }
    
     public function dispatch($currentPath) {
      foreach ($this->routes as $routePath => $callback) {
       if( $routePath === $currentPath) {
        $callback();
       }
      }
      header('HTTP/1.1 ' . $this->responseStatus);
      header('Content-Type: ' . $this->responseContentType);
      header('Content-Length: ' . mb_strlen($this->responseBody));
      echo $this->responseBody;
     }
    
    }

    这里我们需要重点关注addRoute方法,这个方法的参数分别是一个路由路径和一个路由回调,dispatch方法的参数是当前HTTP请求的路径,它会调用匹配的路由回调。第9行是重点所在,我们将路由回调绑定到了当前的App实例上。这么做能够在回调函数中处理App实例的状态:

    $app = new App();
    $app->addRoute(‘user/nonfu', function(){
     $this->responseContentType = ‘application/json;charset=utf8';
     $this->responseBody = ‘{“name”:”LaravelAcademy"}';
    });
    $app->dispatch(‘user/nonfu');
    在Larval底层也有用到bindTo方法,详见Illuminate\Support\Traits\Macroable的__call方法:

    以上所述是小编给大家介绍的PHP匿名函数和闭包详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

    相关文章

    最新评论

  • [放鞭炮][福]玉竹斑斑节日快乐![福][放鞭炮] 2019-05-23
  • 三狮军团首秀 只有两千多球迷观战 2019-05-19
  • 人民网2017呼和浩特徒步迎新活动--内蒙古频道--人民网 2019-05-19
  • 【品牌资讯】环球网斩获“全国行业新闻网站传播力2017年6月榜”多项冠军 2019-05-15
  • 深化对经济工作主线的认识 从供需关系看供给侧结构性改革 2019-05-15
  • 格拉斯哥艺术学院起火 4年前曾遭火灾仍在整修 2019-05-14
  • 回复@地瓜干17世:猪临死才会嚎叫呢~ 2019-05-14
  • 婺源古村溪中发现鹰嘴龟 2019-05-08
  • 编辑评测:高夫净源控油平衡露 极速补水长效控油 2019-05-08
  • 四部门发文规范特色小镇建设防止“新瓶装旧酒” 2019-05-02
  • 【地球的盛会文明的聚会艺术的盛宴四海一家足球为人类和平幸福而荣耀!!!普京是当今人类世界最优秀的一代伟人俄罗斯赢啦!!!】 2019-04-29
  • 学习新思想,千万师生同上一堂课 2019-04-28
  • 你这种个体户都干不了的老蚕也配谈计划?真是笑死人不偿命哦? 2019-04-23
  • 感人!的哥带着患病父亲出车 孝心感动乘客 2019-04-23
  • 图解:习近平在纪念马克思诞辰200周年大会上讲话的16个金句 2019-04-16
  • 幸运飞艇全部开奖记录 排列3和值走势图 gt彩票官网 七乐彩开奖号码多少 北京赛车pk10六码计划 360老时时彩安全购彩 时时彩软件 足彩半全场胜负规则 北京pk10买9码连输 北京pk10计划在线计划 幸运之门彩票网 21點游戏 体育彩票走势图表大全 彩票论坛福彩论坛体彩论坛全国最大 pk10大小单双预测 北京赛车pk10助赢软件