时间:2021-07-01 10:21:17 帮助过:21人阅读
我们都知道,类的私有属性在类外部是不可访问的,包括子类中也是不可访问的。比如如下代码:
class Example1{
private $_prop = 'test';
}
$r = function(Example1 $e){
return $e->_prop;
};
$a = new Example1();
var_dump($r($a));
//运行结果:Fatal error: Cannot access private property Example1::$_prop
?>
但某些情况下我们需要访问类的私有属性,有下面这么几种方法可以实现:1.利用反射
class Example1{
private $_prop = 'test';
}
$r = function(Example1 $e){
return $e->_prop;
};
$a = new Example1();
$rfp = new ReflectionProperty('Example1','_prop');
$rfp->setAccessible(true);
var_dump($rfp->getValue($a));
//结果
输出:string 'test' (length=4)
?>
2.利用Closure::bind()
此方法是php 5.4.0中新增的。
class Example1{
private $_prop = 'test';
}
$r = function(Example1 $e){
return $e->_prop;
};
$a = new Example1();
$r = Closure::bind($r,null,$a);
var_dump($r($a));
//结果
输出:string 'test' (length=4)
?>
另外,我们也可以用引用的方式来访问,这样我们就可以修改类的私有属性:
class Example1{
private $_prop = 'test';
}
$a = new Example1();
$r = Closure::bind(function & (Example1 $e) {
return $e->_prop;
}, null, $a);
$cake = & $r($a);
$cake = 'lie';
var_dump($r($a));
//结果
输出:string 'lie' (length=3)
$reader = function & ($object, $property) {
$value = & Closure::bind(function & () use ($property) {
return $this->$property;
}, $object, $object)->__invoke();
return $value;
};
?>
Closure::bind()还有一个很有用之处,我们可以利用这一特性来给一个类动态的添加方法。官方文档中给了这么一个例子:
trait MetaTrait
{
private $methods = array();
public function addMethod($methodName, $methodCallable)
{
if (!is_callable($methodCallable)) {
throw new InvalidArgumentException('Second param must be callable');
}
$this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class());
}
public function __call($methodName, array $args)
{
if (isset($this->methods[$methodName])) {
return call_user_func_array($this->methods[$methodName], $args);
}
throw RunTimeException('There is no method with the given name to call');
}
}
class HackThursday {
use MetaTrait;
private $dayOfWeek = 'Thursday';
}
$test = new HackThursday();
$test->addMethod("addedMethod",function(){
return '我是被动态添加进来的方法';
});
echo $test->addedMethod();
//结果
输出:我是被动态添加进来的方法
?>
以上就介绍了php中类外部访问类私有属性的方法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。