PHP callback: Is there an equivalent for ::class for a method of a class?

Viewed 498

In PHP it is possible to get a full class name via class name resolution like this:

Example:

namespace Name\Space;
class ClassName {}

echo ClassName::class;

Output: Name\Space\ClassName

This is better than using the string Name\Space\ClassName directly in the code because code introspection especially in IDEs can find an error directly.

I wonder if there is something similar for methods of a class - this would be specifically useful for callback functions.

This is how you can basically can pass a callback:

$a = function($callback,$arg) { return $callback($arg); }

$a('getInfo',5);

Instead of passing a string here (which might change), I would prefer to do something like this:

$a(MyClass::class::getInfo,5);

With I "go to declaration" click in the IDE I could go directly to getInfo plus I see errors in case with method does not exist anymore. Is there a way to achieve what I want to do here?

2 Answers

In fact, you work with callable type. And PHP allows setting method/function name only as a string. But if you use classes and objects you will have a different way to set callback. For example:

$a = function($callback, $arg) { 
   return call_user_func($callback, $arg)); 
}

// call a static method of the class with 
// using fullname space and method name as a string
$a('Name\Space\MyClass::getInfo',5); 

// call a static method of the class 
// with using ::class 
$a([MyClass::class, 'getInfo'], 5);

// call a method of an object 
$myObject = new MyClass();
$a([$myOject, 'getInfo'], 5);

Three possibilities.

(1)

echo `__CLASS__`;

...returns namespace\classname as a string.

(2)

If you're trying to get the namespace\classname from another class, i.e., not the one where you're currently executing code, then I would suggest setting a public property inside each class such as:

public static $classname = __CLASS__;

which you could then access from anywhere as:

ClassName::$classname

Put it in each of your classes. Always use the same property name.

(3)

Have you considered the PHP function debug_backtrace() which returns a call stack with the most recent call at index = 0;

So, if:

$caller = debug_backtrace();

Then, $caller[0]['class'] contains the fully qualified class name, including any namespace, at the point where you called debug_backtrace().

I'm guessing that #2 is the solution that will work for you.

Just thought of a 4th possibility that doesn't depend on you adding any code to each class. Might add some overhead though, but so does my 3rd solution above.

(4)

$declared_classes = get_declared_classes();

This lists all of the classes currently declared within the PHP scope as fully qualified namespace\classname. You could search the returned array for partial string matches within the array and return the whole namespace\classname string.

One thing to keep in mind. You might have duplicates if different namespaces have same-named classes.

Related