28
define('anActionType', 1);
$actionTypes = array(anActionType => 'anActionType');
class core {
    public $callbacks = array();
    public $plugins = array();
    public function __construct() {
        $this->plugins[] = new admin();
        $this->plugins[] = new client();
    }
}
abstract class plugin {
    public function registerCallback($callbackMethod, $onAction) {
        if (!isset($this->callbacks[$onAction]))
            $this->callbacks[$onAction] = array();

        global $actionTypes;
        echo "Calling $callbackMethod in $callbacksClass because we got {$actionTypes[$onAction]}" . PHP_EOL;

        // How do I get $callbacksClass?

        $this->callbacks[$onAction][] = $callbackMethod;
    }
}
class admin extends plugin {
    public function __construct() {
        $this->registerCallback('onTiny', anActionType);
    }
    public function onTiny() { echo 'tinyAdmin'; }
}
class client extends plugin {
    public function __construct() {
        $this->registerCallback('onTiny', anActionType);
    }
    public function onTiny() { echo 'tinyClient'; }
}
$o = new core();

$callbacksClass should be admin or client. Or am I missing the point here completely and should go about this another way? It should be noted that I will only accept an answer that does not require me to send the classname as an argument to the registerCallback method.

Mark Tomlin
  • 8,593
  • 11
  • 57
  • 72
  • 1
    Erm, both methods are instance methods (not statics), so if you really need the class name for another purpose then just echoing it (i.e. calling the callback), you have to provide an instance rather then a classname probably... – Wrikken Sep 01 '10 at 21:14

4 Answers4

78

If anyone came here looking for how to get the name of a calling class from another class like I did, check this out https://gist.github.com/1122679

EDIT: pasted code

function get_calling_class() {

    //get the trace
    $trace = debug_backtrace();

    // Get the class that is asking for who awoke it
    $class = $trace[1]['class'];

    // +1 to i cos we have to account for calling this function
    for ( $i=1; $i<count( $trace ); $i++ ) {
        if ( isset( $trace[$i] ) ) // is it set?
             if ( $class != $trace[$i]['class'] ) // is it a different class
                 return $trace[$i]['class'];
    }
}

EG

class A {
    function t() {
        echo get_calling_class();
    }
}

class B {
    function x() {
        $a = new A;
        $a->t();
    }
}

$b = new B;
$b->x(); // prints B
hamstar
  • 1,787
  • 4
  • 16
  • 23
  • 3
    I think that if you put the code on here you'll get more of an upvote then just mine. (Although, I do love GitHub, it's just that it would be better if the source code for this was hosted here.) – Mark Tomlin Aug 04 '11 at 13:48
  • Cheers for that. Helped me out. – Ne Ma Jul 23 '15 at 10:36
  • Could you explain why you need to loop through the stacktrace? In my version, I just look if the stack count is egal or over 3 then I return `$stack[2]['class']`. I am return the second index because my method is within a class called by another class that wants to know which class calls it. So, I want to know **A** that calls `B::method` that uses the `Reflector::getCallerClass` method. – Master DJon Jun 08 '22 at 14:08
18

Use get_class():

$this->callbacks[$onAction][] = $callbackMethod;
$className = get_class($this);

// Call callback method
$className->$callbackMethod();
Mike Mackintosh
  • 13,917
  • 6
  • 60
  • 87
Theodore R. Smith
  • 21,848
  • 12
  • 65
  • 91
4

You should really do something like:

$this->registerCallback(array($this, 'onTiny'), anActionType);

That is how PHP works with handles to object methods.

Matthew
  • 47,584
  • 11
  • 86
  • 98
  • That's how the PHP internal callback functions (like preg_replace_callback) work, but not his class. His class would break if he used that syntax. – Theodore R. Smith Sep 01 '10 at 18:38
  • 2
    He should change his class to work with normal PHP callbacks, unless there's a very good reason not to. – Matthew Sep 01 '10 at 18:43
2

From PHP 8+ you can use static::class rather than get_class($this).

This one is also auto-fixed with PHP Code Sniffer and rule SlevomatCodingStandard.Classes.ModernClassNameReference

Arxeiss
  • 976
  • 16
  • 34