PHP 5引入了魔术方法__get()和__set()。根据我的理解,这是必须编写每个成员的getter和setter的捷径;
<?php
class Person {
private $firstname;
private $lastname;
function __set($var, $name) {
$this->$var = $name;
}
function __get($var) {
return $this->$var;
}
}
$person = new Person();
$person->firstname = "Tom";
$person->lastname = "Brady";
echo $person->firstname . " " . $person->lastname;
// print: Tom Brady
?>
我的问题是,这就像将成员变量公之于众。
class Person {
public $firstname;
public $lastname;
}
这不符合OOP原则吗?那有什么意义呢?
答案 0 :(得分:3)
在你的例子中,将它们公开是一回事。但是,你的__set&amp; __get函数不必处理所有变量。 (可能使用switch语句来决定要处理哪个。)此外,您可以对__set的参数执行数据验证,或者计算根本不存在的__get的返回值。
注意到您在代码中使用了$ this-&gt; var而不是$ this-&gt; $ var(这是我认为您希望代码正常工作的原因)
答案 1 :(得分:2)
需要理解的是,“OOP原则”不是一成不变的。 它们更像是经验法则。
因此,例如在python中,所有成员变量都是公共的。没有真正的私人变量。
在Smalltalk中,所有变量都是私有的,如果要提供对需要getter的变量的访问,则没有公共变量。事实上,这里是吸气者和制定者的实践所在。
因此,php中的神奇getter和setter在很多情况下都很有用。 例如:
现在,如果你想保留私有变量,仍然使用魔法getter和setter 再次针对您的应用程序的特定情况,您可以修改您的代码 对私有变量使用'_'下划线约定。
<?php
class Person {
private $_firstname;
private $_lastname;
function __set($name, $value) {
if (!strpos('_', $name) === 0) {
$this->$name = $value;
} else {
throw new Exception ("trying to assign a private variable");
}
}
function __get($name) {
if (!strpos('_', $name) === 0) {
retrun $this->$name;
} else {
throw new Exception ("trying to read a private variable");
}
}
}
?>
答案 2 :(得分:0)
首先,您的示例不起作用,因为您正在访问$this->var
。
第二:是的,添加魔术套装和吸气剂就像添加制定者和吸气剂一样。只是魔术。
__set和__get有用:如果你正在构建一个像ORM这样的库,它可能会派上用场。此外,它可以用作穷人的属性:如果你最初公开了一个字段,你现在可以在__set和__get中添加行为,就像它总是在那里一样(例如,验证)。