tags:

views:

48

answers:

4

I have a big list of properties that I need to map between two objects, and in one, the value that I need to map is buried inside an array. I'm hoping to avoid hard-coding the property names in the code.

If I have a class like this:

class Product {
    public $colors, $sizes;
}

I can access the properties like this:

$props = array('colors', 'sizes');
foreach ($props as $p) {
    $this->$p = $other_object->$p;
}

As far as I can tell, if each of the properties on the left are an array, I can't do this:

foreach ($props as $p) {
    $this->$p[0]['value'] = $other_object->$p;
}

Is that correct, or am I missing some clever way around this?

(This is in drupal, but I don't really think that matters.)

A: 

I don't understand your problem. This works:

class Test {
    public $prop = "prov value";
}
$arr = array(array("prop"));
$test = new Test();
$test->$arr[0][0] = "new prop value";
var_dump($test);

result:

object(Test)#1 (1) {
  ["prop"]=>
  string(14) "new prop value"
}
Artefacto
Your example doesn't do what I need. You're setting $test->prop to a value; In my case, $test->prop itself is an array, and I need to set a portion of that. The curly braces above work.
sprugman
+4  A: 

I believe you can wrap it in curly braces {}:

foreach ($props as $p) {
    $this->{$p}[0]['value'] = $other_object->$p;
}

Edit:

Okay. Now my brain turned on. Sorry for the confusing edits.

awgy
this is the proper technique to dynamically set object properties
mike clagg
+1  A: 

Also try this:


$props = get_object_vars($this);
mike clagg
tumbs up for great answer.
powtac
A: 
foreach ($props as $p) {
    $this->{$p}[0]['value'] = $other_object->{$p};
}

It's called variable, variables.

Mark Tomlin
`$p` on the first go-round would be `'colors'`. `$$p` would try to access `$colors` to use as the property name, which is not desired here, since `$colors` is not a defined variable.Remove the extra `$` in `$$p` and you're good.
awgy
Thank you @awgy. Credit should really go to you for this one then.
Mark Tomlin