阅读"这个"和"使用"来自PHP闭包的参数

时间:2017-09-11 05:01:03

标签: php closures php-7.1

当您创建一个在PHP中返回闭包的方法时:

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

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

print_r的结果包含this(其方法创建闭包的类)和static,它们似乎是在use ()语句中绑定的值。封闭:

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

print_r($closure);

产:

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

然而,我不能为我的生活找出如何捕捉这些价值观。如果没有收到以下内容,则无法使用任何形式的财产访问者(例如$closure->static$closure->{'static'}):

  

PHP致命错误:未捕获错误:Closure对象不能在XYZ中拥有属性。

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

  

PHP致命错误:未捕获错误:无法在XYZ中使用Closure类型的对象作为数组。

JSON编码对象,除此之外,如果这些值对象无效,则提供空JSON对象{},并且使用ReflectionFunction类不提供对这些项的访问。

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

除了输出缓冲和解析print_r或类似的东西之外,我实际上无法找到获取这些值的方法。

我错过了一些明显的东西吗?

  

注意:用例是用于实现memoization,这些值对于识别呼叫是否与之前的缓存呼叫匹配非常有用。

2 个答案:

答案 0 :(得分:5)

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

查看ReflectionFunction::getClosureThis()方法。我通过搜索zend_get_closure_this_ptr()中定义的zend_closures.c来查看PHP 7源代码来跟踪它。

本手册目前没有很多关于此功能的文档。我使用的是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)
}

答案 1 :(得分:-1)

为了获得$ 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帮助您。