来自Java,我只有几次假期访问PHP。看看魔法获取和设置方法,我(受Java影响)的肚子开始受到伤害:看起来好像是直接访问属性(当然,你实际上是在使用__get和__set)。
所以 - 除了你必须编写的代码少之外,使用magic getter和setter方法而不是传统的getX()/ setX()方法有什么好处吗?我应该在编写PHP时开始使用它们吗?
谢谢,最好!
答案 0 :(得分:2)
__get()
的唯一好处是可以减少代码,但即便如此,情况也不一定如此。例如,如果您有一组10个私有成员,并且您希望getter显示5,那么您必须编写__get()
,以便在调用其中一个伪可见成员时发送它。否则,您要么发出错误(否则会在没有__get()
的情况下自然发生错误,或者返回可能实际上没有帮助的null
等值。
我必须谴责任何建议一般使用吸气剂和制定者的人。这通常表明架构存在问题。解释以下两个代码块之间的概念差异,例如:
class _ {
public $_;
}
VS
class _ {
private $_;
public function get_() {
return $this->_;
}
}
没有区别。
但是,正如许多人会指出使用getter的优势在于,这允许您以某种方式透明地修改返回值,以使其对收件人有用。但是,我们回到架构问题。您根本不应该出于任何原因公开类的内容。相反,您应该告诉班级执行一个动作(可能会根据其状态而有所不同)。使用getter通常可以根据查看的状态查询类的状态并在外部执行操作。
我对__set()
和setter基本上有相同的论点,但__set()
允许你做一件好事:
class _ {
private $_ = array();
public function __set($key, $val) {
$this->_[$key] = $val;
}
}
这可以让您输入非常好的$_obj->key = 'val'
。请注意,与此没有太大区别,并添加另一个方法,例如add()
,它接受键和值并执行相同的操作,我只是更喜欢对象设置符号。
答案 1 :(得分:1)
__get__
和__set__
完全是动态的。因此,例如,如果调用它们以启用延迟加载,则可以启动数据库请求。当然,你也可以使用getter和setter来做到这一点,但是你每次都必须这样做。您也可以执行类似AOP的操作,因为每个属性调用都通过一个方法传递。总而言之,__get__/__set__
提供了更多的灵活性,以及他们处理的时间。你可以用它做真正的高级/酷炫的东西。
答案 2 :(得分:1)
优点是,当您进行重构时,可以处理直接分配/读取而无需立即更改完整的代码库,代码可能会更短,并且人们可以更轻松地创建字符串(例如: $title="<title>{$obj->title}</title>";
与$title='<title>'.$obj->getTitle().'</title>';
。
然而,__get
&amp; __set
方法可能会很快变得庞大而且难以处理,并且在正确编码时明确地说,我认为使用显式set/getX()
方法更好地调用明确的函数,并且代码详细程度的微小增加是我认为合理的,因为人们可以很容易地看到实际调用函数的内容什么不是。可能的异常可能是你为另一个类/对象构建一个装饰器,但那就是它。
答案 3 :(得分:1)
getter和setter方法以及__set()
和__get()
方法之间几乎没有区别!这些都是神奇的方法!
当您想要将未定义状态分配给对象时使用__set()
,因此__get()
也用于获取未定义状态的值!
setter和getter用于分配或获取已定义状态的值
答案 4 :(得分:0)
除了你必须编写的代码少,使用magic getter和setter&gt;方法而不是传统的getX()/ setX()方法有什么好处吗?我应该在编写PHP时开始使用它们吗?
鉴于编写代码的代码较少,已经是开始使用它们的有力理由 另一个原因是你可以为你的所有getter / setter添加一个共同的行为
function __set() {
//> Do some code in common between all setter
//> set your var here
}
答案 5 :(得分:0)
为每个属性编写getX()/ setX()时,实际上,您至少需要7行代码。这假设您的开始方法大括号与定义位于同一行,并且您只将一行代码放入方法中,然后您将自己的大括号放在自己的行上。
对于一个非平凡的对象,将其乘以6(YMMV)。这是42行仅用于属性访问/变异。那不包括输入验证或规范化。如有其他选择,请查看:https://github.com/metaphp/attributes
答案 6 :(得分:0)
动态编程存在开销(例如使用魔术方法)。旧基准:Benchmarking magic
由于PHP是一种动态(而不是完全企业)语言,在许多情况下(减少代码行并且缺少一些纳秒)似乎是个好主意(用于调试,可伸缩性,减少错误等。)