【问题标题】:Faking a closure's function name伪造闭包的函数名
【发布时间】:2015-02-13 04:46:09
【问题描述】:

不说长话,我有一个这样的场景:

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 函数。这是我正在调用的第三方代码示例,它考虑了调用它的人的函数名称以便做某事。

【问题讨论】:

  • @Anthony,如果您可以使用eval(),您可以查看我更新后的答案。
  • 为什么回溯如此重要?您正在处理的实际问题是什么?
  • 我觉得需要很长时间才能解释清楚,因为有很多层特殊情况。但简而言之,我使用的是 Laravel Eloquent ORM(与 Neo4j 和 NeoEloquent 混合),我试图通过父类中的 __call() 动态声明关系方法,但 Laravel 使用方法名称本身作为其逻辑的一部分.这不是我能改变的。因此,我将整个场景简化为上面的核心问题。

标签: php closures


【解决方案1】:

你可以把名字传给doSomething()like

$this->doSomething($method);

或者像闭包一样

$c = function($func_name) { $this->doSomething($func_name); };
$c($method);

doSomething 中,您可以使用该参数。

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

【讨论】:

  • 我认为 op 说他不能修改 doSomething
  • @FélixGagnon-Grenier 我想那是在我发布这个之后。
【解决方案2】:

在不改变 doSomething() 中的任何内容的情况下,我唯一能想到的就是使用 eval()

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

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

【讨论】:

  • 很遗憾,我无法控制 doSomething()。我的课只是简化了整个场景。
  • 这是一个有趣的想法 - 我会试一试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多