有没有办法禁止从类的实例向类添加属性?

Posted

技术标签:

【中文标题】有没有办法禁止从类的实例向类添加属性?【英文标题】:Is there a way to disable adding properties into a class from an instance of the class? 【发布时间】:2012-01-27 16:53:06 【问题描述】:

有没有办法禁止将properties 从类的实例添加到类中。

我的意思是:

考虑这个类:

class a 
 private $v1;
 public $v2;

 function func()
 ...
 

如果我这样做:

$ins = new a;
$ins->temp = "A variable created from outside the class! C*ap!";
var_dump($ins);

输出:

对象(a)#1 (3) ["v1":"a":private]=> 空值 [“v2”]=> 空值 [“温度”]=> string(48) "从类外部创建的变量!C*ap!"

Can this be disabled?`

【问题讨论】:

【参考方案1】:

也许你可以实现__set() 并从那里抛出异常:

class a 
    private $v1;
    public $v2;

    public function __set($name, $value) 
        throw new Exception("Cannot add new property \$$name to instance of " . __CLASS__);
    

【讨论】:

是的,它是可行的。谢谢你的信息。有没有更优雅的方法?就像我覆盖 php 的默认 __set() 方法一样。我猜这会涉及到一些计算开销。 这种开销是不可避免的,我担心,因为 PHP 允许通过简单地将新属性添加到实例而不重载来创建新属性。 没有计算开销。 __set 仅在您尝试设置不存在的变量时才被调用。它根本不适用于$v2,并且仅在您尝试从外部类设置它的值时才适用于$v1(因为私有声明)。由于您在 __set() 方法中抛出异常,因此可以确保它在正常操作下永远不会被调用,因此没有任何开销。 但是如果在这种情况下曾经调用过__set(),那么您的代码中就有一个错误。生产代码不会在紧密循环中数百万次调用此__set() 方法,因此无需担心任何性能问题。我认为@ThinkingMonkey 担心这会使 every 变量操作变慢,这绝对不是这种情况:这 not 会覆盖 PHP 的“默认”__set() 方法,它只是为其添加一些额外的行为。 当您在 PHP 中为实例变量设置值时,它会首先查找该变量。如果存在,则直接设置该值,并且永远不会调用 __set()。如果实例变量不存在(或者由于private 声明而无法访问),那么它将调用__set()。如果__set() 不存在,那么它要么创建变量,要么抛出异常(在私有变量的情况下)。

以上是关于有没有办法禁止从类的实例向类添加属性?的主要内容,如果未能解决你的问题,请参考以下文章

Eiffel:有没有办法禁止使用任何特别继承的创建方法?

有没有办法禁止我的类的子类化?

COM Interop的重命名/前缀类

VB禁止文本框输入

有没有办法声明实体类的字段不是持久属性?

在 Java 中,是不是可以在运行时使用反射将成员变量添加到类中?