代码示例:
Class People {
// private property.
private $name;
// other methods not shown for simplicity.
}
直接前进。让我假设$name
是一个PRIVATE类成员(或属性,变量,字段,根据需要调用它)。有没有办法在PHP中执行这些操作:
$someone = new People();
$someone->name = $value;
$somevar = $someone->name;
没有使用__get($name)
和__set($name, $value)
。
我需要检查指定的$value
,因此我只需要一个这样的getter setter:
getName();
setName($value);
并不一定像这样的getter setter魔术方法重载:
__get($value);
__set($value, $name);
也就是说,我只需要一个吸气剂装置。但那不是我想要的。它只是感觉不像面向对象,因为来自静态类型语言(如C ++或C#)的人可能会感觉和我一样。
有没有办法在不使用getter setter魔术方法重载的情况下在C#中获取和设置私有属性?
更新
我对使用魔术方法和显式getter setter之间的性能开销感到好奇,因此我为这两种方法创建了自己的基准测试,希望它对任何阅读此内容的人都有用。
使用magic方法和method_exist:
(点击here查看代码)
使用显式getter setter:
(点击here查看代码)
也就是说,使用魔术方法和方法的setter和getter只需要比显式getter setter成本高2倍。我认为将它用于中小型系统仍然可以接受。
不。
然而,使用__get
和__set
分别作为getName()
和setName($val)
的动态代理有什么问题?就像是:
public function __get($name) {
if (method_exists($this, 'get'.$name)) {
$method = 'get' . $name;
return $this->$method();
} else {
throw new OutOfBoundsException('Member is not gettable');
}
}
这样你就不会把所有东西都塞进一个怪物方法中,但是你仍然可以使用$foo->bar = 'baz';
语法和私有/受保护的成员变量......
ReflectionClass is your salvation
我知道Hendra为时已晚,但我相信它对其他许多人都有帮助。
在PHP核心中,我们有一个名为ReflectionClass的类,它可以操作对象范围内的所有内容,包括属性和方法的可见性。
在我看来,它是PHP中有史以来最好的类之一。
让我举个例子:
如果你有一个私有属性的对象,你想从外面修改它
$reflection = new ReflectionClass($objectOfYourClass);
$prop = $reflection->getProperty("PrivatePropertyName");
$prop->setAccessible(true);
$prop->setValue($objectOfYourClass, "SOME VALUE");
$varFoo = $prop->getValue();
使用方法eighter可以做同样的事情;
我希望我能帮忙;
如果使用魔法属性似乎不正确,正如其他海报已经指出的那样,你也可以考虑ReflectionClass::getProperty和ReflectionProperty::setAccessible。
或者在类本身上实现必要的getter和setter方法。
为了回应您提出的语言功能问题,我要说动态类型语言与静态类型语言不同。每个具有OOP的编程语言都有所不同:Object-Oriented Languages: A Comparison。
class conf_server
{
private $m_servidor="localhost";
private $m_usuario = "luis";
private $m_contrasena = "luis";
private $m_basededatos = "database";
public function getServer(){
return $this->m_servidor;
}
public function setServer($server){
$this->m_servidor=$server;
}
public function getUsuario(){
return $this->m_usuario;
}
public function setUsuario($user){
$this->m_usuario=$user;
}
public function getContrasena(){
return $this->m_contrasena;
}
public function setContrasena($password){
$this->m_contrasena=$password;
}
public function getBaseDatos(){
return $this->m_basededatos;
}
public function setBaseDatos($database){
$this->m_basededatos->$database;
}
}