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