PHP中如何将Callable/Closure存储为类属性?报错求助
在PHP中存储Callable/Closure为类属性的实现方案
当然可以实现将callable或Closure存储为类属性的需求,你遇到的错误主要和PHP版本兼容性以及类型声明规则有关,下面逐个分析并给出解决方案:
错误原因解析
1. $modifier cannot have type callable
这个错误出现在PHP 7.3及更早版本中——PHP 7.4才正式支持在类属性上使用callable作为类型声明,低版本不允许直接给类属性指定callable类型。
2. Argument #1 ($modifier) must be of type callable, string/array given
字符串形式的'SomeOtherClass::func'、数组形式的['SomeOtherClass', 'func']本身都是合法的callable类型,出现这个错误大概率是因为PHP版本过低(比如低于5.2,这类版本对callable的识别范围有限),或者代码执行时SomeOtherClass还未被定义导致PHP无法识别该callable的合法性。
正确实现方案
根据你的PHP版本选择对应的写法:
方案一:PHP 7.4及以上版本(推荐)
直接使用callable作为属性类型,支持所有合法的callable形式(字符串、数组、匿名函数等):
class MyClass { protected callable $modifier; public function __construct(callable $modifier) { $this->modifier = $modifier; } // 示例:调用存储的callable public function execute() { return ($this->modifier)(); } } class SomeOtherClass { public static function func() { return ['a' => 'b']; } } // 三种合法传入方式都可正常工作 $test1 = new MyClass('SomeOtherClass::func'); $test2 = new MyClass(['SomeOtherClass', 'func']); $test3 = new MyClass(fn() => ['a' => 'custom']); // 测试调用 print_r($test1->execute()); // 输出 Array ( [a] => b )
方案二:PHP 7.3及更早版本
由于低版本不支持callable属性类型,可改用Closure作为属性类型,通过Closure::fromCallable()将任意合法callable转换为Closure存储:
class MyClass { protected Closure $modifier; public function __construct(callable $modifier) { // 将传入的callable转换为Closure对象 $this->modifier = Closure::fromCallable($modifier); } public function execute() { $closure = $this->modifier; return $closure(); } } class SomeOtherClass { public static function func() { return ['a' => 'b']; } } // 传入数组形式的callable $test = new MyClass(['SomeOtherClass', 'func']); print_r($test->execute()); // 输出 Array ( [a] => b )
注意事项
- 确保传入的callable对应的类、方法在代码执行时已经被定义,否则PHP无法识别其合法性。
- 如果使用类的非静态方法作为callable,需要传入包含实例的数组,比如
[$instance, 'methodName']。
内容的提问来源于stack exchange,提问作者user2173353
相关产品推荐
相关产品推荐

