伪造一个闭包的函数名

时间:2014-12-15 05:49:07

标签: php closures

遗漏了一个长篇故事,我有这样的场景:

class Foo {

  function doSomething() {
    print "I was just called from " . debug_backtrace()[1]['function'];
  }

  function triggerDoSomething()
  {
    // This outputs "I was just called from triggerDoSomething".  
    // This output makes me happy.
    $this->doSomething();
  }

  function __call($method, $args)
  {
    // This way outputs "I was just called from __call"
    // I need it to be "I was just called from " . $method
    $this->doSomething();

    // This way outputs "I was just called from {closure}"
    // Also not what I need.
    $c = function() { $this->doSomething() };
    $c();

    // This causes an infinite loop
    $this->$method = function() { $this->doSomething() };
    $this->$method();
  }
}

如果我调用$ foo-> randomFunction(),我需要将输出读作“我刚从randomFunction调用”

有没有办法命名一个闭包或以不同的方式处理这个问题?

注意:我无法更改doSomething功能。这是我正在调用的第三方代码的示例,它考虑了为了做某事而调用它的函数名称。

2 个答案:

答案 0 :(得分:1)

您可以将名称传递给doSomething(),如

$this->doSomething($method);

或像

这样的闭包
$c = function($func_name) { $this->doSomething($func_name); };
$c($method);

并且在doSomething中您可以使用该参数。

function doSomething($method) {
    print "I was just called from " . $method;
}

答案 1 :(得分:0)

我在doSomething()中不改变任何内容的唯一想法是使用eval()

function __call($method, $args)
{
    eval("
         function {$method}(\$self) {
              \$self->doSomething();
         }

         {$method}(\$this);
    ");
}