14

是否可以一次为 php 中的对象设置多个属性?而不是这样做:

$object->prop1 = $something;
$object->prop2 = $otherthing;
$object->prop3 = $morethings;

做类似的事情:

$object = (object) array(
    'prop1' => $something,
    'prop2' => $otherthing,
    'prop3' => $morethings
);

不覆盖对象

4

7 回答 7

23

不像你想要的那样。但这可以通过使用循环来完成。

$map =  array(
    'prop1' => $something,
    'prop2' => $otherthing,
    'prop3' => $morethings
);

foreach($map as $k => $v)
    $object->$k = $v;

只看到 2 条额外的行。

于 2012-05-03T15:53:36.483 回答
10

您应该查看面向对象的 PHP 最佳实践

“由于 setter 函数返回 $this,您可以像这样链接它们:”

 $object->setName('Bob')
        ->setHairColor('green')
        ->setAddress('someplace');

顺便说一下,这被称为流利界面

于 2012-05-03T16:04:13.940 回答
5

我建议你要这样做。说真的,不要

您的代码第一种方式要干净得多,它更清楚您的意图,并且您不会将您的代码混淆到将来某个时候有人会查看您的代码并思考“白痴到底在想什么”的程度?

如果你坚持做一些显然是错误的事情,你总是可以创建一个数组,迭代它并在一个循环中设置所有属性。不过我不会给你代码。这是邪恶的。

于 2012-05-03T15:57:39.647 回答
2

您可以为返回对象的对象编写一些设置器:

public function setSomething($something)
{
 $this->something = $something;
 return $this; //this will return the current object
}

然后你可以这样做:

$object->setSomething("something")
       ->setSomethingelse("somethingelse")
       ->setMoreThings("some more things");

您需要为每个属性编写一个设置器,因为__set函数无法返回值。

或者,设置一个函数来接受一组属性 => 值并设置所有内容?

public function setProperties($array)
{
  foreach($array as $property => $value)
  {
    $this->{$property} = $value;
  }
  return $this;
}

并传入数组:

$object->setProperties(array('something' => 'someText', 'somethingElse' => 'more text', 'moreThings'=>'a lot more text'));
于 2012-05-03T15:58:14.277 回答
1

我意识到这是一个老问题,但为了其他遇到它的人的利益,我最近自己解决了这个问题并想分享结果

<?php
    //Just some setup
    header('Content-Type: text/plain');
    $account = (object) array(
        'email' => 'foo',
        'dob'=>((object)array(
            'day'=>1,
            'month'=>1,
            'year'=>((object)array('century'=>1900,'decade'=>0))
        ))
    );
    var_dump($account);
    echo "\n\n==============\n\n";

    //The functions
    function &getObjRef(&$obj,$prop) {
        return $obj->{$prop};
    }

    function updateObjFromArray(&$obj,$array){
        foreach ($array as $key=>$value) {
            if(!is_array($value))
                $obj->{$key} = $value;
            else{
                $ref = getObjRef($obj,$key);
                updateObjFromArray($ref,$value);
            }
        }
    }

    //Test
    updateObjFromArray($account,array(
        'id' => '123',
        'email' => 'user@domain.com',
        'dob'=>array(
            'day'=>19,
            'month'=>11,
            'year'=>array('century'=>1900,'decade'=>80)
        )
    ));
    var_dump($account);

显然没有内置保护措施。主要的警告是该updateObjFromArray函数假定对于 中的任何嵌套数组$array,相应的键 in$obj已经存在并且是一个对象,这必须是真的,否则将其视为对象会引发错误。

希望这可以帮助!:)

于 2016-09-08T13:18:03.153 回答
0

我实际上不会这样做....但为了好玩我会

$object = (object) ($props + (array) $object);

你最终得到一个由 $objects 公共属性组成的 stdClass,所以它失去了它的类型。

于 2012-05-03T16:11:05.923 回答
0

objectThis()将类数组属性或数组转换为 stdClass 的方法。使用直接 transtypage (object) 将删除数字索引,但使用此方法将保留数字索引。

public function objectThis($array = null) {
    if (!$array) {
        foreach ($this as $property_name => $property_values) {
            if (is_array($property_values) && !empty($property_values)) {
                $this->{$property_name} = $this->objectThis($property_values);
            } else if (is_array($property_values) && empty($property_values)) {
                $this->{$property_name} = new stdClass();
            }
        }
    } else {
        $object = new stdClass();
        foreach ($array as $index => $values) {
            if (is_array($values) && empty($values)) {
                $object->{$index} = new stdClass();
            } else if (is_array($values)) {
                $object->{$index} = $this->objectThis($values);
            } else if (is_object($values)) {
                $object->{$index} = $this->objectThis($values);
            } else {
                $object->{$index} = $values;
            }
        }
        return $object;
    }
}
于 2014-02-16T10:13:33.563 回答