我将尝试使用这个问题的格式,我非常愿意接受有关更好的方法来处理它的建议.
我不想只是在问题中转储一堆代码,所以我已经发布了该类的代码refactormycode
.
基类,便于类属性处理
我的想法是人们可以在这里发布代码片段或进行更改refactormycode
并将链接发布回他们的重构.基于此,我会做出投票并接受答案(假设有一个明确的"赢家").
无论如何,对班级本身:
我看到很多关于getter/setter类方法的争论,最好是直接访问简单的属性变量,还是每个类都定义了明确的get/set方法,等等等等等等.我喜欢使用显式方法的想法,以防您以后需要添加更多逻辑.然后,您不必修改使用该类的任何代码.但是我讨厌有一百万个看起来像这样的函数:
public function getFirstName() { return $this->firstName; } public function setFirstName($firstName) { return $this->firstName; }
现在我确定我不是第一个这样做的人(我希望有一个更好的方法可以让别人向我建议).
基本上,PropertyHandler类有一个__call魔术方法.通过__call以"get"或"set"开头的任何方法然后被路由到将值设置或检索到关联数组的函数.获取或设置后,数组中的键是调用方法的名称.因此,如果进入__call的方法是"getFirstName",则数组键是"FirstName".
我喜欢使用__call,因为它会自动处理子类已经定义了"getFirstName"方法的情况.我的印象(我可能错了)是__get和__set魔术方法不这样做.
所以这是一个如何工作的例子:
class PropTest extends PropertyHandler { public function __construct() { parent::__construct(); } } $props = new PropTest(); $props->setFirstName("Mark"); echo $props->getFirstName();
请注意,PropTest实际上没有"setFirstName"或"getFirstName"方法,PropertyHandler也没有.所有这一切都是在操纵数组值.
另一种情况是你的子类已经扩展了其他东西.由于PHP中不能具有真正的多重继承,因此可以使子类具有PropertyHandler实例作为私有变量.您必须再添加一个函数,但事情的行为方式完全相同.
class PropTest2 { private $props; public function __construct() { $this->props = new PropertyHandler(); } public function __call($method, $arguments) { return $this->props->__call($method, $arguments); } } $props2 = new PropTest2(); $props2->setFirstName('Mark'); echo $props2->getFirstName();
请注意子类如何使用__call方法将所有内容传递给PropertyHandler __call方法.
反对以这种方式处理getter和setter的另一个好理由是它很难记录.
实际上,基本上不可能使用任何类型的文档生成工具,因为不存在未记录的显式方法.
我现在几乎放弃了这种方法.这是一个有趣的学习练习,但我认为它牺牲了太多的清晰度.
我这样做的方式如下:
class test { protected $x=''; protected $y=''; function set_y ($y) { print "specific function set_y\n"; $this->y = $y; } function __call($function , $args) { print "generic function $function\n"; list ($name , $var ) = split ('_' , $function ); if ($name == 'get' && isset($this->$var)) { return $this->$var; } if ($name == 'set' && isset($this->$var)) { $this->$var= $args[0]; return; } trigger_error ("Fatal error: Call to undefined method test::$function()"); } } $p = new test(); $p->set_x(20); $p->set_y(30); print $p->get_x(); print $p->get_y(); $p->set_z(40);
将输出(为清晰起见添加换行符)
generic function set_x specific function set_y generic function get_x 20 generic function get_y 30 generic function set_z Notice: Fatal error: Call to undefined method set_z() in [...] on line 16