Find out which class called a method in another class

后端 未结 8 2030
时光说笑
时光说笑 2020-11-27 06:10

Is there a way in PHP to find out what object called what method in another object.

Exmaple:

class Foo
{
  public function __construct()
  {
    $bar         


        
相关标签:
8条回答
  • 2020-11-27 06:34

    @Pascal MARTIN: Yes, in normal applicacions it's probably not needed. But sometimes it could be useful. Consider an example from my own app:

    There's a Controller subclass which can use a Template object to prepare its output. Every template has a name to refer it to. When a Controller needs a Template, it asks the TemplateManager for it by giving that name as a parameter. But there could be many template files with that name for different Controllers. Controlers are used as plugins, and may be written by different users, so the names used by them can't be controlled to no collide with each other. Namespaces for templates are needed. So TemplateManager, which is a factory for Template objects, needs the template name and the namespace name to locate the proper template source file. This namespace is related to the particular Controller's class name.

    But, in most cases, each Controller will be using templates from its own namespace and only in rare cases from other namespaces. So specifying the namespace in each call to TemplateManager::getTemplate() each time would be a mess. It's better if namespace is optional and defaults to... the Controller which calls the TemplateManager::getTemplate()! And here's a good place for knowing the caller.

    Of course the caller Controller could pass itself or its name as a parameter, but it doesn't really differ much from passing the namespace name. It couldn't be optional in either way.

    But if you can know the caller, you can use that information to default the namespace automatically inside the getTemplate(), without even bothering the caller. It doesn't have to know how getTemplate() is handling it in its inside and how does it know the proper default namespace. He only needs to know that it does, and that it can pass any other namespace optionally if it really needs to.

    0 讨论(0)
  • 2020-11-27 06:35
    var_dump(getClass($this)); 
    

    Used in a method in namespace B this will give you the class that called a method in namespace B from namespace A.

    0 讨论(0)
  • 2020-11-27 06:37

    You can probably achieve this with a debug backtrace, though this seems kind of hackish.

    Your alternative option is to pass a parameter to that class and tell it where it is being called from, when you instantiate the class from within another.

    0 讨论(0)
  • 2020-11-27 06:41

    At the very least, you could use debug_backtrace and analyze that to find the calling method.

    I think you should also be able to do it using the reflection API, but it's been too long since I've used PHP and I don't remember exactly how. The links should at least get you started, however.

    0 讨论(0)
  • 2020-11-27 06:44

    you could use debug_backtrace, a bit like this :
    BTW, take a look at the comments on the manual page : there are some useful functions and advices given ;-)

    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();
    

    The var_dump would output :

    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
    

    and the echo :

    called by Foo :: __construct
    

    But, as nice as it might look like, I am not sure it should be used as a "normal thing" in your application... Seems odd, actually : with a good design, a method should not need to know what called it, in my opinion.

    0 讨论(0)
  • 2020-11-27 06:57

    Here is one liner solution

    list(, $caller) = debug_backtrace(false, 2);
    

    As of PHP7 this won't work based on the docs: http://php.net/manual/en/function.list.php as we cannot have empty properties, here is a small update:

    list($childClass, $caller) = debug_backtrace(false, 2);
    
    0 讨论(0)
提交回复
热议问题