当前位置:Gxlcms > PHP教程 > php中类外部访问类私有属性的方法

php中类外部访问类私有属性的方法

时间: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教程有兴趣的朋友有所帮助。

人气教程排行