olanod
olanod

Reputation: 30606

PHP Object, set multiple properties

Is it possible to set multiple properties at a time for an object in php? Instead of doing:

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

do something like:

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

but without overwriting the object.

Upvotes: 16

Views: 29739

Answers (7)

taylor8294
taylor8294

Reputation: 76

I realise this is an old question but for the benefit of others that come across it, I solved this myself recently and wanted to share the result

<?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' => '[email protected]',
        'dob'=>array(
            'day'=>19,
            'month'=>11,
            'year'=>array('century'=>1900,'decade'=>80)
        )
    ));
    var_dump($account);

Obviously there are no safeguards built in. The main caveat is that the updateObjFromArray function assumes that for any nested arrays within $array, the corresponding key in $obj already exists and is an object, this must be true or treating it like an object will throw an error.

Hope this helps! :)

Upvotes: 1

Gino
Gino

Reputation: 69

Method objectThis() to transtypage class array properties or array to stdClass. Using direct transtypage (object) would remove numeric index, but using this method it will keep the numeric index.

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;
    }
}

Upvotes: 0

goat
goat

Reputation: 31854

I wouldn't actually do this....but for fun I would

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

you end up with an stdClass composed of $objects public properties, so it loses its type.

Upvotes: 0

Manos Dilaverakis
Manos Dilaverakis

Reputation: 5879

You should look at Object Oriented PHP Best Practices :

"since the setter functions return $this you can chain them like so:"

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

This incidentally is known as a fluent interface.

Upvotes: 12

Richard Parnaby-King
Richard Parnaby-King

Reputation: 14891

You could write some setters for the object that return the object:

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

You could then do:

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

You would need to write a setter for each property as a __set function is not capable of returning a value.

Alternatively, set a single function to accept an array of property => values and set everything?

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

and pass in the array:

$object->setProperties(array('something' => 'someText', 'somethingElse' => 'more text', 'moreThings'=>'a lot more text'));

Upvotes: 3

Madara&#39;s Ghost
Madara&#39;s Ghost

Reputation: 175098

I would recommend you don't do it. Seriously, don't.

Your code is much MUCH cleaner the first way, it's clearer of your intentions, and you aren't obfocusing your code to the extent where sometime in the future someone would look at your code and think "What the hell was the idiot thinking"?

If you insist on doing something which is clearly the wrong way to go, you can always create an array, iterate it and set all the properties in a loop. I won't give you code though. It's evil.

Upvotes: 5

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57690

Not like the way you want. but this can be done by using a loop.

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

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

See only 2 extra lines.

Upvotes: 25

Related Questions