This RFC proposes the syntax func_name::function
for generating a callback value at runtime with correctly resolved class and function names.
The string and array formats for callbacks present difficulties for users and IDEs:
PHP would provide a syntax, similar to a function call, which evaluates to a string or array callback value. This would be composed of the usual function call syntax, but replacing the parameter list and surrounding parenthesis with ::function
. For example, to create the callback “Foo::bar”
, one would use the expression Foo::bar::function
.
Under the proposal, the following expressions (within a namespace NS
and a class Foo
) would evaluate as true:
func::function === 'NS\\func'; \func::function === 'func'; CN::meth::function === 'NS\\CN::meth'; \CN::meth::function === 'CN::meth'; self::meth::function === 'NS\\Foo::meth'; $obj->meth::function === [$obj, 'meth']; parent::{'meth'}::function === ['NS\\Foo', 'parent::meth'];
namespace NS1; use NS2\Bee as B; class A { static function init() { $inst = new self; var_export($inst->bar::function); $inst->bar(); } function bar() { var_export(B::baz::function); } } function c() {} var_export(var_export ::function); var_export(A::init ::function); A::init(); var_export(c ::function);
At runtime, these values would be passed to var_export
:
'var_export'; 'NS1\\A::init'; [$inst, 'bar']; 'NS2\\Bee::baz'; 'NS1\\c';
As function
is a reserved word, it should not be misinterpreted as a constant or method in previous versions (this idea borrowed from Ralph Schindler’s class_name_scalars RFC). If the implementation reused the T_FUNCTION token, the syntax would be case-insensitive.
Any other use of ::function
should throw a parse error. Although it may be reasonable to suggest supporting syntaxes like ($callable)::function
(evaluating to the value of $callable
), I believe this would not provide much benefit and would complicate the spec.
As it is permitted between a function name and its argument list, for consistency and flexibility, whitespace should be permitted before the ::function
tokens. It's not clear whether whitespace would improve or worsen readability of the expression in practice; this will likely depend on how syntax highlighters display the ::function
tokens.
::function
would give authors a straightforward and reliable way to specify correctly-formed callbacks without being tripped up by namespaces and use
statements. Callback expressions would also be more clearly recognized as such by the reader, and by IDEs and static analysis tools.