简体   繁体   English

什么是PHP中的Closure :: bind()

[英]What is Closure::bind() in PHP

The PHP manual offers little explanation about Closure::bind() and the example was confusing too. PHP手册没有提供关于Closure :: bind()的解释,这个例子也令人困惑。

Here's the code example on the site: 这是网站上的代码示例:

class A {
private static $sfoo = 1;
private $ifoo = 2;
}
$cl1 = static function() {
return A::$sfoo;
};
$cl2 = function() {
return $this->ifoo;
};

$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo $bcl1(), "\n";
echo $bcl2(), "\n";

What are the parameters for Closure::bind()? Closure :: bind()的参数是什么?

Null was used in the above, and even the "new" keyword was used too, which makes this even more confusing to me. 上面使用了Null,甚至使用了“new”关键字,这让我更加困惑。

If you put the value of $cl2 as a method of class A , the class looks like this: 如果将$cl2的值作为类A的方法,则该类如下所示:

class A {
    public $ifoo = 2;

    function cl2()
    {
        return $this->ifoo;
    }
}

and you can use it like this: 你可以像这样使用它:

$x = new A();
$x->cl2();
# it prints
2

But, because $cl2 is a closure and not a member of class A , the usage code above does not work. 但是,因为$cl2是一个闭包而不是A类的成员,所以上面的用法代码不起作用。

The method Closure::bindTo() allows using the closure as it were a method of class A : Closure::bindTo()允许使用闭包,因为它是A类的方法:

$cl2 = function() {
    return $this->ifoo;
};

$x = new A();
$cl3 = $cl2->bindTo($x);
echo $cl3();
# it prints 2

$x->ifoo = 4;
echo $cl3();
# it prints 4 now

The closure uses the value of $this but $this is not defined in $cl2 . 闭包使用$this的值但$this未在$cl2定义。 When $cl2() runs, $this is NULL and it triggers an error ( "PHP Fatal error: Using $this when not in object context" ). $cl2()运行时, $thisNULL并且它会触发错误( “PHP致命错误:在不在对象上下文中时使用$this )。

Closure::bindTo() creates a new closure but it "binds" the value of $this inside this new closure to the object it receives as its first argument. Closure::bindTo()创建一个新的闭包,但它将这个新闭包内的$this的值“绑定”到它接收的对象作为其第一个参数。

Inside the code stored in $cl3 , $this has the same value as the global variable $x . $cl3存储的代码中, $this与全局变量$x具有相同的值。 When $cl3() runs, $this->ifoo is the value of ifoo in object $x . $cl3()运行时, $this->ifoo是对象$xifoo的值。

Closure::bind() is the static version of Closure::bindTo() . Closure::bind()Closure::bindTo()的静态版本。 It has the same behaviour as Closure::bindTo() but requires an additional argument: the first argument must be the closure to bind. 它与Closure::bindTo()具有相同的行为,但需要一个额外的参数:第一个参数必须是要绑定的闭包。

If you prefer to use static version, just try to 如果您更喜欢使用静态版本,请尝试

$cl4 = Closure::bind(function () { return $this->ifoo; }, new A(), 'A');
echo $cl4();
// it returns "2"

It is pretty cool, if you wanna update the property of an object, but there is no 'setter' for the property. 如果你想更新一个对象的属性,它很酷,但是没有'setter'属性。 For example: 例如:

class Product {
  private $name;
  private $local;
  public function __construct(string $name) {
    $this->name = $name;
    $this->local = 'usa':
  }
}
$product1 = new Product('nice product');
echo $product1->local;
// it returns 'usa'

$product2 = \Closure::bind(function () {
  $this->local = 'germany';
  return $this;
}, new Product('nice product'), 'Product');
echo $product2->local;
// it returns 'germany'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM