7

I really hate to write this question because I'm kind-of "research guy" and, well, I always find what I'm searching for... But this one bugs me a lot and I can't find the answer anywhere... So, here it goes:

As the title says I need to get a method name with the trailing class and namespace path as a string. I mean something like this: "System\Language\Text::loadLanguageCache". As we know, you can get a class name (with full namespace path) by typing, i.e.: Text::class and it returns "System\Language\Text", but is there a way to get this for a method? Something like: Text::loadLanguageCache::function to get string: "System\Language\Text::loadLanguageCache"?

Edit:

I think I should explain this further... I know about magic constant __METHOD__ but the problem is that it works inside the called method and I need this "outside the method". Take this as example:

//in System\Helpers
function someFunction()
{ return __METHOD__; }

That's all OK with this if I call the function I'll get (let's assume that method is in System\Helpers class) - "System\Helpers::someFunction". But what I want is this:

//in System\Helpers
function someFunction()
{ //some code... whatever }

// somewhere not in System\Helpers
function otherFunction()
{
    $thatFunctionName = Helpers::someFunction::method //That imaginary thing I want

    $thatClassName = Helpers::class; //this returns "System\Helpers"
}

I hope this cleared my question a bit :)

10
  • 1
    $thatFunctionName = Helpers::someFunction::method; - that was the imaginary line, because method thing does not exist. Of course I could just type: $thatFunctionName = 'System\Helpers::someFunction'; but that is just not nice because of refactoring, possible namespace changes, class name changes and so on :) Commented Nov 30, 2013 at 16:06
  • 2
    I think the reason this wouldn't be useful is that methods rarely need to be represented in a fully-qualified form like that. For a callback, for instance, you'd use an array: [Helpers::class, 'someFunction']; and for an instance (non-static) method, a string with :: in it would be just plain wrong. So take the qualified class name and, for your purposes, append '::someFunction' as a hard-coded string, since it's hard-coded even in your imaginary syntax. Commented Nov 30, 2013 at 16:44
  • 1
    I want that whole string because I send it as an AJAX parameter and I don't want two separate strings for class and method (PHP calls it to handle request using reflection). Concatenating that string is all fine, I just thought there is kind of "nicer" way :) Commented Nov 30, 2013 at 17:09
  • 2
    i'm looking for this because i use laravel and i don't want the controller actions (what methods from what classes to call) in my routes to be expressed inside strings like 'UserController@authenticate'... using a string, i don't have the benefits of code refactoring in my IDE... would like to know if you found a way around this. Commented Dec 8, 2014 at 3:46
  • 2
    Such an underrated question. It is these fine details that make you love and adore your code. It can be much more difficult to find references to a method if you hard-code strings like that, but an equivalent of ::class as ::method instead would be such a blessing for fine code. I have not found the solution online yet that we seem to look for, but I think it can also be difficult to formulate this issue--specifically--as a simple, searchable question. Any luck, 6 years later? Commented Nov 21, 2020 at 11:02

2 Answers 2

3

You must use the magic constant, you can read more about at Magic constants in php.net

__METHOD__

Outside of the class you must use Reflection as is explained at ReflectionClass documentation:

<?php
$class = new ReflectionClass('ReflectionClass');
$method = $class->getMethod('getMethod');
var_dump($method);
?>;

Returns:

object(ReflectionMethod)#2 (2) {
  ["name"]=>
  string(9) "getMethod"
  ["class"]=>
  string(15) "ReflectionClass"
}
Sign up to request clarification or add additional context in comments.

3 Comments

I know about this magic constant, but it works inside a method, and I need this to work "outside" the method...
Yeah, that's what I want, and I know about Reflection too. But the whole idea of a question was the simplicity, to just use Foo::someMethod::method to get that string (as easily as you can do with Foo::class). :)
But the class name not is obvious but the method yes, just $methodPath = Helpers::class . 'theMethod'; you cannot use AS in methods. :/
0

I needed this too, since putting the namespace in a string will give double backslashes, bad when renaming namespaces.

Solution extended from the remark from IMSoP here above.

Use this:

$callable = [\namespace\classname::class, 'method'];

When called:

$callable($arg1, $arg2) ; 

Will be exactly like calling

\namespace\classname::method($arg1, $arg2);

For instance:

<?php

namespace xxx\yyy;

class myClass {
    
    static function methodA(string $name) {
        echo 'method A called, '.$name.'. ';
    }
    
    function methodB(string $name) {
        echo 'method B called, '.$name.'. ';
    }
}

$callableA = [myClass::class, 'methodA'];
$callableB = [new myClass, 'methodB'];

var_dump($callableA);
var_dump($callableB);

$callableA("madam");
$callableB('sir');

Results in:

array(2) {
  [0]=>
  string(15) "xxx\yyy\myClass"
  [1]=>
  string(7) "methodA"
}
array(2) {
  [0]=>
  object(xxx\yyy\myClass)#1 (0) {
  }
  [1]=>
  string(7) "methodB"
}
method A called, madam. method B called, sir. 

IMSoP gave the right answer in a remark for most people who search this subject. In 11 years, they didn't bother to make it the answer, so I will, since I almost overlooked it when searching for the subject myself.

Not 100% what the OP asked for, but 100% what most people will actually need! (Since what else than a callable is why you would want the name?)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.