我们有两个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()将它们合并,但如果这样我们不能说我们感到自豪。


当前回答

考虑到对象A和B,有一个非常简单的解决方案:

foreach($objB AS $var=>$value){
    $objA->$var = $value;
}

这是所有。你现在有了objA和objB的所有值。

其他回答

您可以创建另一个对象,将对魔术方法的调用分派给底层对象。下面是你如何处理__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;

为了保存合并对象的方法和属性,可以创建一个组合子类

在__construct上取任意数量的对象 使用__call访问任何方法 使用__get访问任何属性


class combinator{
function __construct(){       
    $this->melt =  array_reverse(func_get_args());
      // array_reverse is to replicate natural overide
}
public function __call($method,$args){
    forEach($this->melt as $o){
        if(method_exists($o, $method)){
            return call_user_func_array([$o,$method], $args);
            //return $o->$method($args);
            }
        }
    }
public function __get($prop){
        foreach($this->melt as $o){
          if(isset($o->$prop))return $o->$prop;
        }
        return 'undefined';
    } 
}

简单的用

class c1{
    public $pc1='pc1';
    function mc1($a,$b){echo __METHOD__." ".($a+$b);}
}
class c2{
    public $pc2='pc2';
    function mc2(){echo __CLASS__." ".__METHOD__;}
}

$comb=new combinator(new c1, new c2);

$comb->mc1(1,2);
$comb->non_existing_method();  //  silent
echo $comb->pc2;

合并任意数量的原始对象

function merge_obj(){
    foreach(func_get_args() as $a){
        $objects[]=(array)$a;
    }
    return (object)call_user_func_array('array_merge', $objects);
}

\ArrayObject类可以交换当前数组以断开原始引用。为此,它提供了两个方便的方法:exchangeArray()和getArrayCopy()。剩下的就是所提供对象的ArrayObjects公共属性的简单array_merge():

class MergeBase extends ArrayObject
{
     public final function merge( Array $toMerge )
     {
          $this->exchangeArray( array_merge( $this->getArrayCopy(), $toMerge ) );
     }
 }

用法如下:

 $base = new MergeBase();

 $base[] = 1;
 $base[] = 2;

 $toMerge = [ 3,4,5, ];

 $base->merge( $toMerge );