简体   繁体   中英

Determine the name of the calling class (parent or child) in parent class method

Looking for a clean way to determine the class (in this case, either parent or child class) of the method that calls a method in the parent class.

I thought late static binding could handle this, but seems like that only really works for calling a static method directly, and not from within an instantiated object's method.

Consider the following:

abstract class ParentClass {

    public function parentMethod() {
        self::_log("parent.non.static");
    }

    public static function parentStatic() {
        self::_log("parent.static");
    }

    public static function getClassName() {
        return __CLASS__;
    }

    protected static function _log($key) {
        $prefix = 'graphite.key.prefix';
        $class  = static::getClassName(); // gets the object's class, not calling class

        $g_key = "{$prefix}.{$class}.{$key}";
        echo "{$g_key} \n";

        // Graphite::increment($g_key);
    }
}

class ChildClass extends ParentClass {

    public function childMethod() {
        self::_log("child.non.static");
    }

    public static function childStatic() {
        self::_log("child.static");
    }

    public static function getClassName() {
        return __CLASS__;
    }
}


$obj = new ChildClass;

$obj->childMethod();           // graphite.key.prefix.ChildClass.child.non.static
$obj->parentMethod();          // graphite.key.prefix.ChildClass.parent.non.static

ParentClass::parentStatic();   // graphite.key.prefix.ParentClass.parent.static
ChildClass::childStatic();     // graphite.key.prefix.ChildClass.child.static

Looking for a clean way to get the class that calls the _log() method without having to pass it in as a parameter. Doesn't have to be static at all, but I was playing around with the late static binding, because I thought that would work, but it just gets the name of the instantiated object, not the child/parent class of the method that calls the _log() method :-/

Edit:

Just to be clear, I'm after getting the class name of the method that called _log() from within the instantiated object (like parentMethod() and childMethod()) Don't care if _log() is static or not. If that makes it easier, fine. But the static ParentClass::parentStatic() and ChildClass::childStatic() were just to show late static bindings and what I figured might work, but not from calling within an instantiated object

get_class will get the class name of a class instance. This can also be called on $this within a class. If you have a class that extends/implements another, $this will refer the the instantiated class, meaning the child class.

Another option is to use debug_backtrace to get the stack of functions that lead up to where you currently are. You can parse the returned array to get whatever you need including line numbers, classes, functions, methods, whatever.

http://php.net/manual/en/function.get-called-class.php

class One {
    public static function test() {
        echo get_called_class() . PHP_EOL;
    }
}

class Two extends One {}

One::test();
Two::test();

Output:

One
Two

Also, according to the top comment in the docs static::class also works as of PHP 5.5.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM