当前位置:  开发笔记 > 编程语言 > 正文

合并两个PHP对象的最佳方法是什么?

如何解决《合并两个PHP对象的最佳方法是什么?》经验,为你挑选了6个好方法。

我们有两个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测试)



1> flochtililoc..:

如果您的对象只包含字段(无方法),则可以:

$obj_merged = (object) array_merge((array) $obj1, (array) $obj2);

当对象具有方法时,这实际上也有效.(使用PHP 5.3和5.6测试)


由此产生的对象将是`stdclass`的实例.虽然它在某种意义上对使用方法的对象"起作用",但它在这种情况下有效地破坏了对象(通过删除方法).
仅仅是我还是这个答案是已经发布了几个月的答案的逐字记录副本?/sf/ask/17360801/

2> 小智..:

如果您的对象只包含字段(无方法),则可以:

$obj_merged = (object) array_merge((array) $obj1, (array) $obj2);



3> Allain Lalon..:

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

祝好运.


好的......然后选择不需要完全重写的方式.
我会编辑他的评论,但你不能这样做.我认为他的意思是迭代者

4> Kornel..:
foreach($objectA as $k => $v) $objectB->$k = $v;


这比PHP版本中接受的答案快7(估计快50%).但是在PHP> = 7时,接受的答案就好了400%.见这里:http://sandbox.onlinephpfunctions.com/code/55a8d53dda932368fd00faca2dd142148ce79d2e

5> Ryan Schumac..:

我理解使用通用对象[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';


只是要指出:在PHP 5.3.0中将调用时传递引用标记为已弃用,并在PHP 5.4.0中删除(导致引发的致命错误).要纠正这个问题:将`foreach($ objects as&$ object)$ this->替换为(&$ object);`使用`foreach($ objects as&$ object)$ this-> with($ object);`纠正了这个问题.资料来源:[http://php.net/manual/en/language.references.pass.php]
另外:`if($ this-> first_precedence)array_push($ this-> composite,&$ object); else array_unshift($ this-> composite,&$ object);`应替换为`if($ this-> first_precedence)array_push($ this-> composite,$ object); else array_unshift($ this-> composite,$ object);`

6> 小智..:

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

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

就这样.您现在拥有objA,其中包含来自objB的所有值.


$ objB将丢失.
推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有