欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

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

程序员文章站 2022-05-11 08:16:00
...

我们都知道,类的私有属性在类外部是不可访问的,包括子类中也是不可访问的。比如如下代码:

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