• 贵州省社科规划办与贵州日报社合作推出“文化贵州”专栏 2019-03-20
  • 就算不为了世界杯,俄罗斯也有那么多时髦好去处值得你飞去 2019-03-20
  • 2018山西英语中考题:浅谈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匿名函数和闭包详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

    相关文章

    • PHP针对多用户实现更换头像功能

      PHP针对多用户实现更换头像功能

      这篇文章主要介绍了PHP针对多用户实现更换头像功能的相关资料,本文分步骤介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
      2016-09-09
    • Symfony2使用第三方库Upload制作图片上传实例详解

      Symfony2使用第三方库Upload制作图片上传实例详解

      这篇文章主要介绍了Symfony2使用第三方库Upload制作图片上传的方法,结合实例形式较为详细的分析了Symfony2使用第三方库Upload的具体步骤与相关使用技巧,需要的朋友可以参考下
      2016-02-02
    • thinkPHP5 tablib标签库自定义方法详解

      thinkPHP5 tablib标签库自定义方法详解

      这篇文章主要介绍了thinkPHP5 tablib标签库自定义方法,结合具体实例形式分析了thinkPHP5标签库的定义、用法及相关注意事项,需要的朋友可以参考下
      2017-05-05
    • PHP防止刷新重复提交页面的示例代码

      PHP防止刷新重复提交页面的示例代码

      我们可以利用 PHP 的 Session 来避免这一点,Session 保存在服务器端,在 PHP 过程中改变 Session 变量的值后,即保存在服务器端,下次访问这个变量时,得到是新赋的值,所以,可以用一个 Session 变量记录表单提交的次数,大于1时,就不再处理表单中的数据
      2015-11-11
    • yii2中关于加密解密的那些事儿

      yii2中关于加密解密的那些事儿

      yii2.0怎么对传输的数据进行加密解密?下面这篇文章就来给大家介绍了yii2中关于加密解密的那些事儿,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
      2018-06-06
    • php实现搜索类封装示例

      php实现搜索类封装示例

      这篇文章主要为大家详细介绍了php实现搜索类封装示例,感兴趣的小伙伴们可以参考一下
      2016-03-03
    • laravel实现批量更新多条记录的方法示例

      laravel实现批量更新多条记录的方法示例

      最近在使用Laravel,想批量插入近千条数据,通过网上找到了相关的解决方法,所以下面这篇文章主要给大家介绍了关于laravel实现批量更新多条记录的相关资料,文中给出了详细的示例代码,需要的朋友们下面随着小编来一起学习学习吧。
      2017-10-10
    • php生成随机数或者字符串的代码

      php生成随机数或者字符串的代码

      一个最简单的利用php生成随机数或者随机字符串的函数.$chars变量中的字符自己修改就能达到数字或者字符串的目的
      2008-09-09
    • php调用dll的实例操作动画与代码分享

      php调用dll的实例操作动画与代码分享

      这是我录制的一个gif操作动画,图片比较大,如果大家在线看图感觉不流畅的话可以把图片保存到本机再看
      2012-08-08
    • 仿dedecms下拉分页样式修改的thinkphp分页类实例

      仿dedecms下拉分页样式修改的thinkphp分页类实例

      这篇文章主要介绍了仿dedecms下拉分页样式修改的thinkphp分页类,可实现类似dedecms下拉分页样式的效果,需要的朋友可以参考下
      2014-10-10

    最新评论

  • 贵州省社科规划办与贵州日报社合作推出“文化贵州”专栏 2019-03-20
  • 就算不为了世界杯,俄罗斯也有那么多时髦好去处值得你飞去 2019-03-20