【发布时间】:2017-08-10 04:55:43
【问题描述】:
让我们从简单的 PHP 代码开始:
<?php
class Test
{
}
$test = new Test();
$test->x = 20;
echo $test->x;
这里的问题是这段代码没有任何问题(在 PHP 7.1 中测试过,可能在某些以前的版本中它也没有任何问题)。
我在这里看到的问题是,当使用这样的代码时,很容易编写很难分析并且可能包含一些隐藏错误的代码。
问题:有什么方法不允许为对象动态创建属性,尤其是在类之外?
对于这样的自定义类,可以使用的解决方案是创建自定义 __set 方法,该方法将创建未声明的属性,如下所示:
public function __set($property, $value)
{
if (!property_exists($this, $property)) {
throw new Exception("Property {$property} does not exit");
}
$this->$property = $value;
}
但它显然不能解决受保护/私有属性的问题 - property_exists 也会为受保护和私有属性返回 true(需要为此使用反射)。
【问题讨论】:
-
__set() 在将数据写入不可访问的属性时运行。 __get() 用于从不可访问的属性中读取数据。魔术方法不能替代 getter 和 setter。它们只允许您处理会导致错误的方法调用或属性访问。因此,还有更多与错误处理相关的内容。另请注意,它们比使用正确的 getter 和 setter 或直接方法调用要慢得多。