如何在PHP可调用闭包函数中访问变量?

r3i60tvu  于 2023-05-05  发布在  PHP
关注(0)|答案(2)|浏览(133)

考虑以下PHP代码:

class Vacation 
{
  protected $onSuccess;
  protected $friend;

  public function onSuccess(callable $callback): self
  {
    $this->onSuccess = $callback;
    return $this;
  }

  public function go()
  {
    echo 'gone' . PHP_EOL;

    $this->friend = 'John';

    call_user_func($this->onSuccess, $this->friend);
  }
}

(new Vacation())
  ->onSuccess(function(){
    echo 'to the beach' . PHP_EOL;
    echo 'with ' . $friend . PHP_EOL; // this doesn't work, $this or self either
  })
  ->go();

是否可以从上面的闭包中以任何方式访问$friend变量?虽然很明显可以将变量传递给call_user_func函数,但我的问题是如何在另一边检索它们,在onSuccess函数中,它存在于Vacation类之外。
快速跟进:如果Vacation类注册了一个示例变量,那么在Vacation类中是否有一个有效的$onSuccess属性类型?

6tqwzwtp

6tqwzwtp1#

您已经在执行带有参数的闭包:

call_user_func($this->onSuccess, $this->friend);

您所缺少的就是将该参数包含在闭包的签名中:

(new Vacation())
  ->onSuccess(function ($friend) {
        echo 'to the beach' . PHP_EOL;
        echo 'with ' . $friend . PHP_EOL;
  })
  ->go();
3b6akqbq

3b6akqbq2#

Manider解决方案很好,但您可以使用这种代码片段

<?php
class Vacation {
protected $onSuccess;
protected $friend;

public function onSuccess( callable $callback ): self {
    $this->onSuccess = $callback;
    return $this;
}

public function getFriend( ) {
    return $this->friend;
}

public function go( ) {
    echo 'gone' . PHP_EOL;
    $this->friend = 'John';
    call_user_func( $this->onSuccess, $this );
}
}

(new Vacation())->onSuccess( function ( $vacation ) {
  echo 'to the beach' . PHP_EOL;
  echo 'with ' . $vacation->getFriend() . PHP_EOL; // this works
  echo 'on a ' . get_class( $vacation ) . PHP_EOL; // also possible to access the object instance
} )->go();

编辑
在call_user_func中,我们传递“$this”作为参数,因此我们传递示例化的Vacation类。
然后,当我们进行链接时,我们创建了一个新的Vacation示例,告诉注册onSuccess回调,它成为一个名为$onSuccess($this-〉onSuccess = $callback)的示例变量,这是一个在调用onSuccess的参数中定义的函数。
此时,新的Vacation已经用protected变量$onSuccess中的函数初始化。然后我们调用go()。
go函数执行回显,将受保护的变量$friend设置为“John”,然后调用保存在$this-〉onSuccess中的函数,并向该函数传递“her self”。
现在php进入定义的函数内部,第一个echo也是如此,第二个echo也是如此,这里我们可以使用$vacation-〉getFriend()来访问受保护的变量。

相关问题