首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >合并两个PHP对象的最佳方法是什么?

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

Stack Overflow用户
提问于 2009-01-18 18:55:19
回答 11查看 200.3K关注 0票数 240

我们有两个PHP5对象,希望将其中一个对象的内容合并到另一个对象中。它们之间没有子类的概念,因此以下主题中描述的解决方案无法应用。

How do you copy a PHP object into a different object type

代码语言:javascript
复制
//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;

备注:

  • 这些是对象,而不是类。
  • 对象包含相当多的字段,因此将非常慢。
  • 到目前为止,我们考虑将对象A和B转换为数组,然后使用array_merge()合并它们,然后再重新转换为对象,但我们不能说我们对此感到自豪。
EN

回答 11

Stack Overflow用户

发布于 2009-01-18 19:18:16

代码语言:javascript
复制
foreach($objectA as $k => $v) $objectB->$k = $v;
票数 32
EN

Stack Overflow用户

发布于 2009-01-18 19:17:34

您可以创建另一个对象,将对魔术方法的调用分派到底层对象。下面是处理__get的方法,但要让它完全工作,您必须覆盖所有相关的魔术方法。你可能会发现语法错误,因为我只是在脑海中输入了它。

代码语言:javascript
复制
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;
    }
  }
}

祝好运。

票数 28
EN

Stack Overflow用户

发布于 2009-05-27 22:12:28

我知道使用泛型对象stdClass()并将它们转换为数组可以回答这个问题,但我认为合成器是一个很好的答案。然而,我觉得它可以使用一些功能增强,并可能对其他人有用。

功能:

obj组合指定引用或克隆合并指定第一个或最后一个条目采用precedence

  • Multiple (两个以上)对象合并,语法与array_merge

  • Method相似链接:$obj->f1()->f2()->f3()...

  • Dynamic

  • :$obj->

(...)

  • /* /* here */ obj

代码:

代码语言:javascript
复制
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;
    }
}

用法:

代码语言:javascript
复制
$obj = new Compositor(use_reference, first_precedence);
$obj->merge([object $object [, object $object [, object $...]]]);
$obj->with([object $object]);

示例:

代码语言:javascript
复制
$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';
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/455700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档