Search code examples
phpstringclassmethodsliterals

PHP:: Fully-qualified method literal to string


Essentially, I seek to pass a static class method to a callback, but do not wish to do so using a hard-coded string, but rather the fully-qualified class method literal. We can do that using classes like so:

$name = NS\FooClass::class;

instead of:

$name = 'NS\FooClass';

which will give us the string of the fully-qualified name of the class. I seek to be able to do something similar for a class method like so:

$name = NS\FooClass::foo_method::method;

instead of:

$name = 'NS\FooClass::foo_method';

It is more manageable and I can use the IDE functionality way better using the literals. Any similar way I can achieve what I want with the class methods without using strings?


Solution

  • As of PHP 8.1, the language has support for "first class callables" using the syntax method_or_function(...), so in this case:

    $callback = FooClass::foo_method(...);
    

    This has the same effect as the older Closure::fromCallable method: it creates a Closure object, like an anonymous function, referring to the referenced method. This can then be used anywhere that a "callable" is expected, instead of specifying the name or an array format.

    The class and method are checked and expanded in exactly the same way as if you were calling the method immediately - e.g. the current namespace and use statements are taken into account, and the resulting method must actually exist.


    For older versions, or some use cases where you want to be able to work with strings, the manual page on the callable type gives two ways to specify a static method for use as a callback:

    • As a string, as in your example 'NS\FooClass::foo_method'
    • As an array where the first part is a class name, and the second part is a the method name: ['NS\FooClass', 'foo_method']

    Since only the class name needs to be qualified with namespace information, you can use ::class with the second syntax to get nearly what you wanted:

    $callback = [NS\FooClass::class, 'foo_method'];
    

    This allows any decent IDE to spot the reference to the class, and allows you to reference it by an imported or aliased name.

    It's worth noting that if the callable type is specified in a parameter or return type declaration or a docblock, some IDEs (e.g. PhpStorm) will "understand" either format as a reference to the method, and include it in features like "find usages" and "go to declaration".