PHP 7匿名类如何访问外部变量?非构造/setter方式实现
PHP匿名类访问外部作用域变量的替代方案
好问题!我当初刚接触PHP匿名类的时候也纳闷过——为啥闭包能用use关键字直接抓外部变量,匿名类就没这语法呢?确实,PHP的匿名类没有直接对应闭包use的原生语法,但咱们有几种巧妙的变通方式,完全不用依赖构造函数传参、setter方法或者公共属性来实现类似效果。
方法1:用内部闭包捕获外部变量
你可以在匿名类的方法里定义一个闭包,通过闭包的use关键字捕获外部作用域的变量,然后在方法里调用这个闭包来获取变量值。这种方式完全封闭,外部看不到任何内部细节:
$outerMessage = "Hi, I'm from the outside!"; $myAnonObj = new class { public function getOuterMessage() { // 用闭包捕获外部的$outerMessage $fetchOuter = function() use ($outerMessage) { return $outerMessage; }; return $fetchOuter(); } }; echo $myAnonObj->getOuterMessage(); // 输出:Hi, I'm from the outside!
这里的关键是:匿名类是在$outerMessage的作用域内创建的,所以其内部方法里的闭包可以通过use正常捕获这个变量,而且整个过程不需要给匿名类传任何参数。
方法2:用Closure::bind绑定外部变量到私有属性
如果需要让匿名类的多个方法都能访问外部变量,可以用Closure::bind创建一个能操作匿名类私有属性的闭包,悄悄把外部变量赋值进去,全程不用暴露公共的set方法:
$secretValue = "My hidden data"; $anonInstance = new class { private $internalStorage; public function readSecret() { return $this->internalStorage; } }; // 创建一个能访问匿名类私有属性的闭包 $assignSecret = Closure::bind( function($value) { $this->internalStorage = $value; }, $anonInstance, get_class($anonInstance) ); // 用闭包把外部变量赋值给私有属性 $assignSecret($secretValue); echo $anonInstance->readSecret(); // 输出:My hidden data
这种方式相当于给匿名类开了个“后门”,但这个后门只有你能控制,外部代码看不到也没法用,完美满足不依赖公共接口的需求。
总结
虽然PHP匿名类没有闭包那样的use语法,但通过内部闭包捕获或者Closure::bind绑定的方式,完全可以实现访问外部作用域变量的效果,而且不用破坏类的封装性。
内容的提问来源于stack exchange,提问作者bruchowski
相关产品推荐
相关产品推荐

