PHP:如何调用静态类属性中的可调用对象?(非call_user_func方案)
问题描述
我有一个静态可调用对象,例如\Foo::bar。将其赋值给普通变量时可以直接调用:
$myCallable = \Foo::class . '::bar'; // 此方式可行 $myCallable('calling this works!');
但如果将其赋值给静态类属性,直接调用会失败:
class MyClass { function myFunc() { static::$myCallable = \Foo::class . '::bar'; static::$myCallable('this does not work'); } }
此时PHP会错误地尝试调用MyClass::Foo::bar(),请问除了使用call_user_func()外,还有其他解决方法吗?
解决方法
以下几种方式可以绕过这个解析歧义问题:
1. 使用数组形式的可调用
PHP支持用数组格式表示可调用对象,结构为[类名, 方法名],将静态属性存储为这种形式后,直接调用不会触发解析错误:
class MyClass { function myFunc() { static::$myCallable = [\Foo::class, 'bar']; // 正常执行调用 static::$myCallable('this works now!'); } }
2. 将属性值转移到临时变量
先把静态属性的值取出赋值给普通变量,再通过变量执行调用,逻辑和普通变量调用完全一致:
class MyClass { function myFunc() { static::$myCallable = \Foo::class . '::bar'; $callable = static::$myCallable; // 正常执行调用 $callable('this works too!'); } }
3. 用闭包包裹目标方法
把目标静态方法包裹成匿名闭包,存储到静态属性中,调用时直接执行闭包即可:
class MyClass { function myFunc() { static::$myCallable = fn(...$args) => \Foo::bar(...$args); // 正常执行调用 static::$myCallable('this works as well!'); } }
内容的提问来源于stack exchange,提问作者joachim
相关产品推荐
相关产品推荐

