我们有两个PHP5对象,并希望将一个内容合并到第二个.它们之间没有子类概念,因此以下主题中描述的解决方案无法应用.
如何将PHP对象复制到不同的对象类型中
//We have this: $objectA->a; $objectA->b; $objectB->c; $objectB->d; //We want the easiest way to get: $objectC->a; $objectC->b; $objectC->c; $objectC->d;
备注:
这些是对象,而不是类.
这些对象包含很多字段,所以foreach会很慢.
到目前为止,我们考虑将对象A和B转换为数组,然后在重新转换为对象之前使用array_merge()合并它们,但我们不能说如果这样我们感到自豪.
flochtililoc.. 414
如果您的对象只包含字段(无方法),则可以:
$obj_merged = (object) array_merge((array) $obj1, (array) $obj2);
当对象具有方法时,这实际上也有效.(使用PHP 5.3和5.6测试)
如果您的对象只包含字段(无方法),则可以:
$obj_merged = (object) array_merge((array) $obj1, (array) $obj2);
当对象具有方法时,这实际上也有效.(使用PHP 5.3和5.6测试)
如果您的对象只包含字段(无方法),则可以:
$obj_merged = (object) array_merge((array) $obj1, (array) $obj2);
您可以创建另一个对象,将对魔术方法的调用分派给底层对象.这是你的处理方式__get
,但为了让它完全运作,你必须覆盖所有相关的魔术方法.您可能会发现语法错误,因为我刚从头脑中输入它.
class Compositor { private $obj_a; private $obj_b; public function __construct($obj_a, $obj_b) { $this->obj_a = $obj_a; $this->obj_b = $obj_b; } public function __get($attrib_name) { if ($this->obj_a->$attrib_name) { return $this->obj_a->$attrib_name; } else { return $this->obj_b->$attrib_name; } } }
祝好运.
foreach($objectA as $k => $v) $objectB->$k = $v;
我理解使用通用对象[stdClass()]并将它们作为数组转换回答问题,但我认为Compositor是一个很好的答案.然而,我觉得它可以使用一些功能增强功能,可能对其他人有用.
特征:
指定引用或克隆
指定优先级的第一个或最后一个条目
多个(两个以上)对象合并,与array_merge的语法相似
方法链接:$ obj-> f1() - > f2() - > f3()...
动态合成:$ obj-> merge(...)/*在这里工作*/$ obj-> merge(...)
码:
class Compositor { protected $composite = array(); protected $use_reference; protected $first_precedence; /** * __construct, Constructor * * Used to set options. * * @param bool $use_reference whether to use a reference (TRUE) or to copy the object (FALSE) [default] * @param bool $first_precedence whether the first entry takes precedence (TRUE) or last entry takes precedence (FALSE) [default] */ public function __construct($use_reference = FALSE, $first_precedence = FALSE) { // Use a reference $this->use_reference = $use_reference === TRUE ? TRUE : FALSE; $this->first_precedence = $first_precedence === TRUE ? TRUE : FALSE; } /** * Merge, used to merge multiple objects stored in an array * * This is used to *start* the merge or to merge an array of objects. * It is not needed to start the merge, but visually is nice. * * @param object[]|object $objects array of objects to merge or a single object * @return object the instance to enable linking */ public function & merge() { $objects = func_get_args(); // Each object foreach($objects as &$object) $this->with($object); // Garbage collection unset($object); // Return $this instance return $this; } /** * With, used to merge a singluar object * * Used to add an object to the composition * * @param object $object an object to merge * @return object the instance to enable linking */ public function & with(&$object) { // An object if(is_object($object)) { // Reference if($this->use_reference) { if($this->first_precedence) array_push($this->composite, $object); else array_unshift($this->composite, $object); } // Clone else { if($this->first_precedence) array_push($this->composite, clone $object); else array_unshift($this->composite, clone $object); } } // Return $this instance return $this; } /** * __get, retrieves the psudo merged object * * @param string $name name of the variable in the object * @return mixed returns a reference to the requested variable * */ public function & __get($name) { $return = NULL; foreach($this->composite as &$object) { if(isset($object->$name)) { $return =& $object->$name; break; } } // Garbage collection unset($object); return $return; } }
用法:
$obj = new Compositor(use_reference, first_precedence); $obj->merge([object $object [, object $object [, object $...]]]); $obj->with([object $object]);
例:
$obj1 = new stdClass(); $obj1->a = 'obj1:a'; $obj1->b = 'obj1:b'; $obj1->c = 'obj1:c'; $obj2 = new stdClass(); $obj2->a = 'obj2:a'; $obj2->b = 'obj2:b'; $obj2->d = 'obj2:d'; $obj3 = new Compositor(); $obj3->merge($obj1, $obj2); $obj1->c = '#obj1:c'; var_dump($obj3->a, $obj3->b, $obj3->c, $obj3->d); // obj2:a, obj2:b, obj1:c, obj2:d $obj1->c; $obj3 = new Compositor(TRUE); $obj3->merge($obj1)->with($obj2); $obj1->c = '#obj1:c'; var_dump($obj3->a, $obj3->b, $obj3->c, $obj3->d); // obj1:a, obj1:b, obj1:c, obj2:d $obj1->c = 'obj1:c'; $obj3 = new Compositor(FALSE, TRUE); $obj3->with($obj1)->with($obj2); $obj1->c = '#obj1:c'; var_dump($obj3->a, $obj3->b, $obj3->c, $obj3->d); // obj1:a, obj1:b, #obj1:c, obj2:d $obj1->c = 'obj1:c';
一个非常简单的解决方案,考虑到你有对象A和B:
foreach($objB AS $var=>$value){ $objA->$var = $value; }
就这样.您现在拥有objA,其中包含来自objB的所有值.