【问题标题】:Why is it possible to access private variables from outside class by reference?为什么可以通过引用从类外部访问私有变量?
【发布时间】:2015-03-13 08:54:23
【问题描述】:

如果我有一个公共类方法返回对不可见(私有或受保护)属性的引用,我可以使用该引用来获得直接访问:

PHP 代码

class A
{
    private $property = 'orange';

    public function &ExposeProperty()
    {
        return $this->property;
    }

    public function Output()
    {
        echo $this->property;
    }
}

$obj = new A();

# prints 'orange'
$obj->Output();

$var = &$obj->ExposeProperty();
$var = 'apple';

# prints 'apple'
$obj->Output();

PHP 中的这个功能背后有什么原因吗?还是只是设计疏忽,未能通过引用跟踪访问违规?

当您想要实现以下目标时,它显然会派上用场:

PHP 代码

$this->load->resource();

其中load 是一个修改$this 的给定属性的对象。但除了这个快捷方式之外,我看不到许多可能的用途,否则这些用途是有效的 OOP 模式所无法实现的。

【问题讨论】:

  • 如果你使用参考文献(更糟糕的是),你应该得到你所得到的:P

标签: php oop


【解决方案1】:

好吧,您正在显式返回对值的引用。您锁定了前门,但随后打开了侧门。您非常刻意地在此处瞄准并射击自己的脚。如果$property 是一个对象,并且您将返回这个对象,不管有没有& 引用,对这个对象的任何修改都会反映在$property 上。这就是 reference 的工作方式,它总是修改引用指向的唯一现有值。

能见度修饰符不是神奇的铁皮“保护”。您可以通过多种方式绕过private 可见性来访问和修改属性。它们主要是向您和其他开发人员表明,此属性不应直接访问,它仅供内部使用,而不是公开认可的 API。 如果您这样做,PHP 会打您的手腕忘记那个。不多也不少。

此外,这里并没有真正违反任何内容。外部代码决不能访问或修改$obj->property。这是private 唯一应该禁止的事情。您实质上是在您的对象上公开了一个公共 API,该 API 修改了 private 属性。通常这是通过 getter 和 setter 函数完成的,但引用 API 显然也可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    相关资源
    最近更新 更多