找出在另一个类中称为方法的类

Bot*_*tto 24 php

在PHP中是否有办法找出哪个对象称为另一个对象中的哪个方法.

〔实施例:

class Foo
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test();
  }
}

class Bar
{
  public function test()
  {
  }
}
$foo = new Foo();
Run Code Online (Sandbox Code Playgroud)

有没有办法让我发现测试方法是从foo对象调用的?

Pas*_*TIN 57

你可以使用debug_backtrace,有点像这样:
BTW,看看手册页上的评论:给出了一些有用的功能和建议;-)

class Foo
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test();
  }
}

class Bar
{
  public function test()
  {
      $trace = debug_backtrace();
      if (isset($trace[1])) {
          // $trace[0] is ourself
          // $trace[1] is our caller
          // and so on...
          var_dump($trace[1]);

          echo "called by {$trace[1]['class']} :: {$trace[1]['function']}";

      }
  }
}
$foo = new Foo();
Run Code Online (Sandbox Code Playgroud)

var_dump将输出:

array
  'file' => string '/home/squale/developpement/tests/temp/temp.php' (length=46)
  'line' => int 29
  'function' => string '__construct' (length=11)
  'class' => string 'Foo' (length=3)
  'object' => 
    object(Foo)[1]
  'type' => string '->' (length=2)
  'args' => 
    array
      empty
Run Code Online (Sandbox Code Playgroud)

echo:

called by Foo :: __construct
Run Code Online (Sandbox Code Playgroud)

但是,尽管它可能看起来很好,但我不确定它应该在您的应用程序中用作"正常的东西"......看起来很奇怪,实际上:有一个好的设计,一个方法不应该知道它叫什么, 在我看来.

  • 工作的例子总是很好.+1.:) (2认同)

Ale*_*kov 17

这是一个班轮解决方案

list(, $caller) = debug_backtrace(false, 2);
Run Code Online (Sandbox Code Playgroud)

从PHP7开始,这将无法根据文档工作:http://php.net/manual/en/function.list.php,因为我们不能有空属性,这里有一个小更新:

list($childClass, $caller) = debug_backtrace(false, 2);
Run Code Online (Sandbox Code Playgroud)

  • 爱一个班轮男人.谢谢 (3认同)

But*_*kus 5

您也可以将调用对象作为参数传递给自己

例如

class Foo
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test($this);
  }
}

class Bar
{
  public function test()
  {
  }
}
$foo = new Foo();
Run Code Online (Sandbox Code Playgroud)

我从Erich Gamma等人在第278页讨论"Mediator"结构模式的"设计模式:可重用的面向对象软件的元素"一书中得到了这个想法.

模式的要点是减少一堆对象/类之间的多对多连接的数量.您创建一个中介类,所有这些类都将其视为中心.这样,课程就不需要彼此了解.中介处理交互.为了让调解者了解它所跟踪的类的变化,他们可以将自己作为参数传递,或者可以使用"观察者"模式实现调解者.

2018年编辑:

我有时使用上面代码的接口,如下所示:

interface someInterface // many classes may implement this interface
{
  public function giveMeBar();
}

class Foo implements someInterface
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test($this);
  }
  public function giveMeBar() {
    return 'Bar';
  }
}
class Bar
{
  public function test(someInterface $a)
  {
    echo $a->giveMeBar();
  }
}
$foo = new Foo(); // prints "Bar"
Run Code Online (Sandbox Code Playgroud)