2

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

6
  • get_class($this) maybe? Commented Dec 15, 2016 at 23:32
  • @JonathanKuhn There's no $this in a static method. Commented Dec 15, 2016 at 23:42
  • 1
    @Barmar OP specifically says that it doesn't have to be static. Commented Dec 15, 2016 at 23:44
  • get_class($this) won't work because it will return the name of the object that was instantiated for $obj, which is ChildClass, and won't ever return ParentClass Commented Dec 15, 2016 at 23:47
  • 1
    Gotcha, so it isn't just child calling parent. It is child calling parent which calls another method under itself. You want parent in that case. Like $instance->childMethod() that calls parent::parentMethod1() that calls self::parentMethod2(). In parentMethod2 you want to show that it was called by parentMethod1 (or really just parent). If that is the case, the only method I know of would be to parse debug_backtrace(). Although, it isn't that bad considering the calling function/class would always be at key 1. Commented Dec 15, 2016 at 23:53

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

7 Comments

that's the same as what I have. I'm looking for getting the class name of the non static method that calls the _log() method from within the instantiated object... calling it from outside the class like that works, obv
@giantNinja so in the _log() method you want to get the name of the calling method?
@giantNinja as you say "parsing debug_backtrace is terribly inefficient and not very clean" which I agree with. My log function calls usually look like $this->log("[%s] A thing happened with %s!", [__METHOD__, $somevar], 'crit'); which gets fed into sprintf() to generate the final message.
yea, mine too... I am logging some stuff in graphite, and part of the key is the class where i'm calling the _log() method from is what I'd like to be able to use, like if I called the _log() method like $this->_log('foo.key', __CLASS__) and used that second parameter as part of the key in _log(), but I'm trying to avoid having to pass that for every method call. It's not the end of the world, but it's just something I thought could be done easily, but idk now
@giantNinja you could always just shoehorn in function _log() { /* ... */; parent::_log(); } to all of your classes and only have to write the extra bits once per class. :P
|
0

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.

2 Comments

This will work for the non-static methods, but there's no $this in static methods.
Right, so the same thing as what's happening here. It will get the class name of the instantiated object (ChildClass in this case), and not the class that called the method. And parsing debug_backtrace is terribly inefficient and not very clean, so that's not what I'm after. I'd rather just pass the class as a param at that point

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.