摘要
代码示例:
Class People {
// private property.
private $name;
// other methods not shown for simplicity.
}
直接往前走。让我假设$name
是私有类成员(或者属性、变量、字段,按您的意愿调用它)。有什么方法可以在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);
话虽如此,我只是需要一个getter策划人。但这不是我想要的,而不是。它只是感觉不像面向对象的,因为来自静态类型化语言(如C++或C# )的人可能和我有同样的感觉。
有没有任何方法可以像在C#中一样在PHP中获取和设置私有属性,而无需使用getter setter魔术方法重载?
更新
为什么不是魔法法?
性能开销基准
我对使用魔术方法和显式getter setter之间的性能开销很好奇,因此我为这两种方法创建了自己的基准测试,希望它能对任何阅读此方法的人有用。
神奇方法的与method_exist:
(单击http://codepad.org/UZtfPQom查看代码)
带有显式getter设置器的:
(单击http://codepad.org/5Cro4yEv查看代码)
也就是说,具有神奇方法和方法的制作者和getter的存在比显式的getter设置器的成本高出2倍。我认为在中小型系统中使用它仍然是可以接受的。
发布于 2011-02-07 19:18:55
不是的。
然而,使用__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';
语法.
发布于 2013-08-19 17:50:05
ReflectionClass is your salvation
我知道对亨德拉来说太晚了,但我相信这对其他人会有帮助。
在PHP中,我们有一个名为ReflectionClass的类,它可以操纵对象范围中的一切,包括属性和方法的可见性。
在我看来,这是PHP中最好的类之一。
让我举一个例子:
如果您有一个具有私有属性的对象,并且您希望从外部修改它
$reflection = new ReflectionClass($objectOfYourClass);
$prop = $reflection->getProperty("PrivatePropertyName");
$prop->setAccessible(true);
$prop->setValue($objectOfYourClass, "SOME VALUE");
$varFoo = $prop->getValue();
同样的事情,你可以用同样的方法来做;
我希望我能帮上忙;
发布于 2011-02-07 19:10:57
如果使用魔法属性看起来不对,正如其他海报已经指出的那样,您也可以考虑ReflectionClass::getProperty和ReflectionProperty::setAccessible。
或者在类本身上实现必要的getter和setter方法。
针对您提出的语言特性问题,我要说,动态类型语言与静态类型语言是不同的。每一种具有OOP的编程语言都有不同的实现方式:面向对象语言的比较。
https://stackoverflow.com/questions/4925317
复制相似问题