美文网首页
PHP闭包的理解是使用

PHP闭包的理解是使用

作者: 云龙789 | 来源:发表于2019-02-25 11:45 被阅读6次

其实学习一个新的概念,除了知道怎么使用,更多的我是想知道它的使用场景。应用场景才是设计的根源。而对于PHP闭包的讲解,大多都是讲解的例子,但是只知道怎么用,还是不知道用在什么时候。这种情况你是不能灵活使用这个知识点的。

  • 以下总结来自于上面推荐文章的总结,但是我觉得是有道理的

1.面向对象变成语言代码的复用主要采用继承来实现,而函数的复用,就是通过闭包来实现。这就是闭包的设计初衷。
2.闭包可以在函数里面访问指定域上午变量,在PHP里使用use关键字来实现。
3.php会自动把闭包函数转换成内置类 Closure 的对象实例,依赖 Closure 的对象实例又给闭包函数添加了更多的能力。
4.Closure::bind 复制一个闭包,绑定指定 this 对象和类作用域。
5.Closure::bindTo 复制当前闭包对象,绑定指定的 this对象和类作用域。

  • demo.php
class Person
{
    public $name = 'test';

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return  $this->name;
    }
}

$closure = function () {
    return $this->name;
};

$person = new Person();
$bindTo =$closure->bindTo($person);
echo $bindTo(); //test
echo '<br>';
$bind = Closure::bind($closure,$person);
echo($bind());//test
echo '<br>';
$person->setName('new test');
echo $bindTo(); // 'new test'
echo '<br>';
echo($bind()); //'new test'
demo打印结果

注意

bindTo -- 是将当前闭包 bindTo(绑定到) 对象
bind -- 是将闭包绑定到对象,第一个参数是闭包,第二个参数是对象
Closure::bind Closure::bindTo 都是闭包的特性,而不是对象
bind 的第二个参数和 bindTo的第三个参数 newscope,是关联到匿名函数的类作用域,或者 'static' 保持当前状态。如果是一个对象,则使用这个对象的类型为心得类作用域。 这会决定绑定的对象的 保护、私有成员 方法的可见性。所以这个对象其实是 class 与 {} 中间的对象名,而不是实例化的那个变量。如果你是在对象中写,可以直接使用 CLASS 表示这个参数。如果不添加这个参数,则不能使用对应的 private、protect 方法或者属性

  • Moderm PHP 对比包的讲解

1.理论上闭包和匿名函数是不同的概念。不过,PHP将其视作相同的概念。所以在PHP语言中闭包其实就是匿名函数
2.PHP闭包和匿名函数的句法和普通函数相同,闭包和匿名函数其实是伪装成函数的对象,它们是Closure 类的实例。闭包和字符串或者整数一样,也是一等值类型。
3.我们之所以能够调用 $closure 变量,使用为这个变量的值是一个闭包,而且闭包对象实现了 _invole() 魔术方法,只要变量后有(),PHP就会查找并调用 _invoke() 方法

  1. PHP闭包是对象。与人任何其他PHP对象类似,每个闭包实例都可以使用 $this 关键字获取闭包的内部状态。闭包对象的默认状态没什么用,不过有一个 __invoke() 魔术方法和一个bindTo()方法,仅此而已
    5.但是,bindTo() 方法为闭包增加了一些有趣的潜力,我们可以使用这个方法把 Closure 对象的内部状态绑定到其他对象上,bindTo(),方法的第二个参数很重要,其作用是指定绑定闭包的那个对象所属的PHP类。因此,闭包可以访问绑定闭包的对象中收保护和私有的成员变量。
    6.你会发现,PHP框架经常使用bindTo()方法把路由URL映射到匿名回掉函数上。框架会把匿名函数绑定到应用对象上,这么做,可以在这个匿名函数中使用$this关键字引用重要的应用对象。
<?php

class App
{
    protected $routes = [];
    protected $responseBody;

    public function addRoute($path, Closure $callback)
    {
        $this->routes[$path] = $callback->bindTo($this,'App');
    }

    public function dispatch($currentPath)
    {
        foreach ($this->routes as $path => $callback) {
            if ($path == $currentPath) {
                echo $callback();
            }
        }
    }

    public function getResponse()
    {
        return $this->responseBody;
    }
}

$app = new App();
$app->addRoute('test', function () {
    $this->responseBody = 'test path';
});

$app->addRoute('name', function () {
    $this->responseBody = 'name path';
});

$app->dispatch('test');
echo $app->getResponse(); // test path
echo '<br>';
$app->dispatch('name');
echo $app->getResponse(); //test path


当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
也就是只要一个对象的变量(比如以下的$adder) 加上一个 (),其实就会调用 __invoke()方法。
而闭包,就相当于是 Closure 类的 __invoke() 方法

  • Closure::call function call ($newThis, ...$parameters) {}
    Closure::call — Binds and calls the closure(绑定一个类,并返回闭包) ----- PHP>=7.0
第一个参数是类的实例化,第二个参数是  __construct() 的参数,return 返回的结果是闭包中返回的结果。
demo 还是上面的那个

$callback = function(){
    return $this->responseBody = 'test path';

};
$app = new App();
$app->addRoute('test', $callback);

echo $callback->call($app);
  • _invoke() 魔术方法的使用
<?php

class Add {
    public $left;
    public $right;

    public function construct($left = 0, $right = 0) {
        $this->left  = $left;
        $this->right = $right;
    }

    public function __invoke() {
        return $this->left + $this->right;
    }
}

$adder = new Add;

$adder->left  = 1;
$adder->right = 2;
echo $adder(); // 3

$adder->left  = 3;
echo $adder(); // 5

相关文章

  • php之闭包函数(Closure)

    php闭包函数(Closure) JS闭包 js和php闭包使用和区别

  • PHP闭包的理解是使用

    PHP 闭包函数及Closure对象的总结 PHP的闭包 其实学习一个新的概念,除了知道怎么使用,更多的我是想知道...

  • Gradle开发-Groovy闭包

    # 闭包 闭包的基础知识 闭包的使用 闭包 this,owner,delegate 的理解 总结 ## 闭包的基础...

  • Python中的闭包

    php对闭包的定义是匿名函数,我之前对python闭包的理解是:外部函数以内部函数作为返回值,称之为闭包!!!(错...

  • JavaScript 作用域闭包

    作用域闭包 启示 对于那些有一点 JavaScript 使用经验但未真正理解闭包概念的人来说,理解闭包可以看作是某...

  • predis操作redis方法大全

    predis是php连接redis的操作库,由于它完全使用php编写,大量使用命名空间以及闭包等功能,只支持php...

  • Predis 中的一些PHP操作redis的方法

    predis是php连接redis的操作库,由于它完全使用php编写,大量使用命名空间以及闭包等功能,只支持php...

  • 闭包和装饰器

    什么是闭包? 各种专业文献的闭包定义都非常抽象,我的理解是:闭包就是能够读取其他函数内部变量的函数。 """ 使用...

  • 前端面试

    说说你对闭包的理解 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内...

  • js面向对象

    1.说说你对闭包的理解 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常...

网友评论

      本文标题:PHP闭包的理解是使用

      本文链接:https://www.haomeiwen.com/subject/pypwyqtx.html