【发布时间】:2012-11-15 05:05:19
【问题描述】:
使用嵌套对象时(ObjTwo 作为 objOne 的属性):
$objOne->property = new ObjTwo($objOne);
最好的沟通方式是什么?以下是我能想到的几种方法:
使用特定的 get/set 方法
class ObjTwo {
__construct($objOne){
$prop1 = $objOne->get_prop1();
// do something with prop1
$prop2 = $objOne->get_prop2();
// do something with prop2
// ... Having to write all these out is kind of a pain
// if you're going to have 20+ vars, and there's no
// easy way to loop through them.
}
}
问题:逐行写出来,当我添加新属性时必须更新它。
我知道建议为每个属性设置一个 get/set 方法,但是我真的很想遍历数据...
get_object_vars() 怎么样
class ObjTwo {
__construct($objOne){
extract(get_object_vars($objOne));
// do something with the vars
}
}
问题:此方法绕过了使用 getter/setter 方法的能力,并且每个属性都必须是公共的才能访问。
动态 getter/setter 方法调用
我考虑过的另一种方法是创建一个字段数组,并有严格的命名 getter/setter 方法的策略:
class ObjTwo {
__construct($objOne){
$prop_array = array('prop1', 'prop2', 'prop_three');
$values = array();
foreach ($prop_array as $prop){
$values[$prop] = $objOne->get_{$prop}();
}
}
}
问题: 每次添加新属性时,我都必须确保正确命名 get_method(),并更新 $prop_array。
谁有更好的解决方案?也许只是构建一个数据数组?:
$objOne->property = new ObjTwo($objOne->get_data());
我喜欢这个解决方案
考虑到这一点,这里有一点澄清:我不想只是从父母到孩子制作相同的副本,反之亦然 - 我编辑了上面的示例以更好地展示这一点。它更多的只是将对象数据的子集从一个地方传递到另一个地方的想法。
不用写了:
$first_name = $this->member->get_first_name();
$last_name = $this->member->get_last_name();
$email = $this->member->get_email();
$display_name = $this->member->get_display_name();
// etc... and
$this->member->set_first_name($first_name);
$this->member->set_last_name($last_name);
$this->member->set_email($email);
$this->member->set_display_name($display_name);
// etc..
有一个$this->member->get_fields('first_name', 'last_name', 'email', 'display_name'); 方法怎么样?我不喜欢准确地记住字段名称(fname、f_name、first_name 等),因此您可以使用类常量:
$data = $this->member->get_fields(array(
Member::FIRST_NAME, Member::LAST_NAME, Member::EMAIL, Member::DISPLAY_NAME
));
这样我就可以遍历返回的数据了。
foreach ($data as $key=>$value) // ...
并设置字段...
$this->member->set_fields(array(
Member::FIRST_NAME => $first_name, // THE BIG ADVANTAGE HERE:
Member::LAST_NAME => $last_name, // These field keys auto-complete
Member::EMAIL => $email, // so you don't have to remember them!
Member::DISPLAY_NAME => $display_name,
// etc...
));
还在想这个……有什么想法吗?
【问题讨论】:
-
您可能想澄清您对“沟通”的定义。你的最终目标是什么?
ObjOne实例暴露了它所拥有的ObjTwo实例的成员? -
你到底想做什么?您是否尝试将对象 A 的所有属性分配给对象 B?为什么?!
-
为什么要将第一个对象复制到第二个?两个对象通过方法或发布/订阅策略进行通信
-
我同意,第一遍有点误导。制作相同的副本不是目标,但通常需要传输数据的一个子集。我进行了一些编辑以反映更通用的用法。另外,我添加了一个我正在考虑实施的答案,对任何意见都感兴趣。
-
整个映射思路是错误的,你不需要这样做。使用常量也不是一个好主意,a)因为不需要整个东西,b)因为常量就是它们......而不是变量。