从 PHP 闭包中读取 "this" 和 "use" 参数

Reading "this" and "use" arguments from a PHP closure

当您创建一个 returns 闭包的方法时 PHP:

class ExampleClass {
  public function test() {
    $example = 10;

    return function() use ($example) {
      return $example;
    };
  }
}

print_r 的结果包含 this(class 的方法创建了闭包)和 static,这似乎是 [= 中绑定的值19=] 闭包语句:

$instance = new ExampleClass();
$closure = $instance->test();

print_r($closure);

制作中:

Closure Object (
    [static] => Array (
        [example] => 10
    )
    [this] => ExampleClass Object()
)

然而,我终其一生都无法弄清楚如何捕捉这些价值。如果不接收以下内容,则无法使用任何形式的 属性 访问器(例如 $closure->static$closure->{'static'}):

PHP Fatal error: Uncaught Error: Closure object cannot have properties in XYZ.

数组访问符号显然也不起作用:

PHP Fatal error: Uncaught Error: Cannot use object of type Closure as array in XYZ.

JSON 对对象进行编码,除了使对象的值无用之外,还提供了一个空的 JSON 对象 {} 并使用 ReflectionFunction class 不提供对这些项目的访问。

closure 文档也没有提供任何访问这些值的方法。

除了做一些可耻的事情,比如输出缓冲和解析 print_r 或类似的东西,我实际上看不到获取这些值的方法。

我是不是遗漏了什么明显的东西?

Note: The use-case is for implementing memoization and these values would be extremely beneficial in identifying whether or not the call matched a previous cached call.

看来您可能忽略了一些 ReflectionFunction 方法。

看看ReflectionFunction::getClosureThis() method. I tracked it down by looking through the PHP 7 source code by doing a search for the zend_get_closure_this_ptr() which is defined in zend_closures.c

手册目前没有很多关于此功能的文档。我正在使用 7.0.9;根据您的示例尝试 运行 此代码:

class ExampleClass {
  private $testProperty = 33;

  public function test() {
    $example = 10;

    return function() use ($example) {
      return $example;
    };
  }
}

$instance = new ExampleClass();
$closure = $instance->test();

print_r($closure);

$func = new ReflectionFunction($closure);
print_r($func->getClosureThis());

您应该得到类似于

的输出
Closure Object
(
    [static] => Array
        (
            [example] => 10
        )

    [this] => ExampleClass Object
        (
            [testProperty:ExampleClass:private] => 33
        )

)

ExampleClass Object
(
    [testProperty:ExampleClass:private] => 33
)

关于闭包静态变量,这些变量返回 ReflectionFunction::getStaticVariables():

php > var_dump($func->getStaticVariables());
array(1) {
  ["example"]=>
  int(10)
}

要获取 $example 的值,您可以试试这个

<?php
class ExampleClass {
    public function test() {
      $example = 10;

      return function() use ($example) {
        return $example;
      };
    }
}

$instance = new ExampleClass();

$number = call_user_func($instance->test(),null);

我在 Laravel 框架中找到了这个解决方案并且对我有用。

call_user_func对你有帮助。