首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在PHP中获取和设置(私有)属性,就像在C#中一样,而无需使用getter setter魔术方法重载

在PHP中获取和设置(私有)属性,就像在C#中一样,而无需使用getter setter魔术方法重载
EN

Stack Overflow用户
提问于 2011-02-07 19:03:49
回答 4查看 8.9K关注 0票数 7

摘要

代码示例:

代码语言:javascript
运行
复制
Class People {
    // private property.
    private $name;

    // other methods not shown for simplicity.
}

直接往前走。让我假设$name私有类成员(或者属性、变量、字段,按您的意愿调用它)。有什么方法可以在PHP中这样做吗:

代码语言:javascript
运行
复制
$someone = new People();
$someone->name = $value;
$somevar = $someone->name;

不使用,使用__get($name)__set($name, $value)

背景

我需要检查指定的$value,因此只需要这样的getter setter:

代码语言:javascript
运行
复制
getName();
setName($value);

不一定是一个getter setter魔术方法重载如下所示:

代码语言:javascript
运行
复制
__get($value); 
__set($value, $name);

话虽如此,我只是需要一个getter策划人。但这不是我想要的,而不是。它只是感觉不像面向对象的,因为来自静态类型化语言(如C++或C# )的人可能和我有同样的感觉。

有没有任何方法可以像在C#中一样在PHP中获取和设置私有属性,而无需使用getter setter魔术方法重载?

更新

为什么不是魔法法?

  1. 有传言说神奇的方法比显式的getter setter方法慢10倍,我还没有测试它,但是记住这是件好事。(发现它没有那么慢,只是慢了2倍,见下面的基准测试结果)
  2. 如果我使用魔术方法,而不是为每个属性将它们分割成不同的函数,就像显式getter setter那样,我必须将所有东西都填充到一个巨大的方法中。(https://stackoverflow.com/questions/4925317/get-and-set-private-property-in-php-as-in-c-without-using-getter-setter-magic/4925483#4925483可能已经满足了这一要求)

性能开销基准

我对使用魔术方法和显式getter setter之间的性能开销很好奇,因此我为这两种方法创建了自己的基准测试,希望它能对任何阅读此方法的人有用。

神奇方法的与method_exist:

(单击http://codepad.org/UZtfPQom查看代码)

  • 吸气时间是0.0004730224609375秒。
  • 赛特花了0.00014305114746094秒。

带有显式getter设置器的:

(单击http://codepad.org/5Cro4yEv查看代码)

  • 吸气时间是0.00020718574523926秒。
  • Setter花费7.9870223999023E-5秒(即0.00007xxx)。

也就是说,具有神奇方法和方法的制作者和getter的存在比显式的getter设置器的成本高出2倍。我认为在中小型系统中使用它仍然是可以接受的。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-07 19:18:55

不是的。

然而,使用__get__set分别作为getName()setName($val)的动态代理有什么问题呢?类似于:

代码语言:javascript
运行
复制
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';语法.

票数 7
EN

Stack Overflow用户

发布于 2013-08-19 17:50:05

代码语言:javascript
运行
复制
ReflectionClass is your salvation

我知道对亨德拉来说太晚了,但我相信这对其他人会有帮助。

在PHP中,我们有一个名为ReflectionClass的类,它可以操纵对象范围中的一切,包括属性和方法的可见性。

在我看来,这是PHP中最好的类之一。

让我举一个例子:

如果您有一个具有私有属性的对象,并且您希望从外部修改它

代码语言:javascript
运行
复制
$reflection = new ReflectionClass($objectOfYourClass);
$prop = $reflection->getProperty("PrivatePropertyName");
$prop->setAccessible(true);
$prop->setValue($objectOfYourClass, "SOME VALUE");
$varFoo = $prop->getValue();

同样的事情,你可以用同样的方法来做;

我希望我能帮上忙;

票数 4
EN

Stack Overflow用户

发布于 2011-02-07 19:10:57

如果使用魔法属性看起来不对,正如其他海报已经指出的那样,您也可以考虑ReflectionClass::getPropertyReflectionProperty::setAccessible

或者在类本身上实现必要的getter和setter方法。

针对您提出的语言特性问题,我要说,动态类型语言与静态类型语言是不同的。每一种具有OOP的编程语言都有不同的实现方式:面向对象语言的比较

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4925317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档