1

Lets say I have:

    class Zebra{
        public static function action(){
            print 'I was called from the '.get_class().' class'; // How do I get water here?
        }
    }

    class Water{
        public static function drink(){
            Zebra::action();
        }
    }

Water::drink();

How do I get "water" from the zebra class?

(This is for php 5.3)

CodeChap
  • 4,132
  • 6
  • 30
  • 40
  • Look into `debug_backtrace`. But you really don't want to be doing that in normal code paths. – Jon Sep 15 '11 at 08:10
  • 2
    Try to do get_called_class() instead. – Matt Sep 15 '11 at 08:11
  • possible duplicate of [PHP: how do I know the caller of a function?](http://stackoverflow.com/questions/3330938/php-how-do-i-know-the-caller-of-a-function) – Gordon Sep 15 '11 at 08:14
  • @Matt that would still be Zebra because this is not an issue of LSB. The OP does call Zebra. – Gordon Sep 15 '11 at 08:14
  • If you need to make decisions based on the Caller, you might want to rethink your design. You should not have that need. – Gordon Sep 15 '11 at 08:19

3 Answers3

3

You can get the caller's info from debug_backtrace http://php.net/manual/en/function.debug-backtrace.php

Ravi
  • 727
  • 6
  • 19
  • Not too keen on using back trace either. - there might not be a solution – CodeChap Sep 15 '11 at 08:19
  • *(related)* [`debug_backtrace` in production code](http://stackoverflow.com/questions/346703/php-debug-backtrace-in-production-code) – Gordon Sep 15 '11 at 08:23
1

Full usable solution using exception, but not debug_backtrace, no need to modify any prototype :

function getRealCallClass($functionName)
{
  try
   {
     throw new exception();
   }
  catch(exception $e)
   {
     $trace = $e->getTrace();
     $bInfunction = false;
     foreach($trace as $trace_piece)
      {
          if ($trace_piece['function'] == $functionName)
           {
             if (!$bInfunction)
              $bInfunction = true;
           }
          elseif($bInfunction) //found !!!
           {
             return $trace_piece['class'];
           }
      }
   }
}

class Zebra{
        public static function action(){
        print 'I was called from the '.getRealCallClass(__FUNCTION__).' class'; 
    }
}

class Water{
    public static function drink(){
        Zebra::action();
    }
}

Water::drink();
1

One not so good solution is : use __METHOD__ or __FUNCTION__ or __CLASS__ . and pass it as parameter to function being called. http://codepad.org/AVG0Taq7

<?php

  class Zebra{
        public static function action($source){
            print 'I was called from the '.$source.' class'; // How do I get water here?
        }
    }

    class Water{
        public static function drink(){
            Zebra::action(__CLASS__);
        }
    }

Water::drink();

?>
DhruvPathak
  • 42,059
  • 16
  • 116
  • 175
  • 1
    that's not the "not so good solution" but the only sane solution. – Gordon Sep 15 '11 at 08:12
  • @gordon , I find it not so good, because he will have to edit an existing code for that. A better solution would have been which could have made this possible without code modification. I am not sure if there exists any. – DhruvPathak Sep 15 '11 at 08:15
  • Thanks, this is how I had it originally, its what I'm trying to avoid. – CodeChap Sep 15 '11 at 08:15
  • @Dhruv that "other" solution would involve debug_backtrace which is bad practise. If the OP needs the information inside that function it should be an argument passed into the function. Anything else breaks encapsulation. – Gordon Sep 15 '11 at 08:16