简体   繁体   中英

Using eval for dynamic nested objects

For a SOAP service I have to generate an object, which can have an arbitrary number of nested objects of the same type. The only working solution I have come up with was one using eval. I have simplified the code somewhat, in reality the objects in the $nestedObjArray are considerably larger.

$nestedObjArray = array();
$nestedObjArray[] = new stdClass();
$nestedObjArray[] = new stdClass();
$nestedObjArray[] = new stdClass();

$finalObj = new stdClass();
for ($i = 0; $i < count($nestedObjArray); $i++) {
    $nestedStr = str_repeat("->nested", $i);
    eval('$finalObj->nested'.$nestedStr.' = $nestedObjArray[$i];');
}

Which generates the following 3 statements:

$finalObj->nested = $nestedObjArray[0];
$finalObj->nested->nested = $nestedObjArray[1];
$finalObj->nested->nested->nested = $nestedObjArray[2];

This works fine, but is pretty ugly. Can anyone think of a more elegant solution? Btw, the following instead of the eval line doesn't work:

$finalObj->nested{$nestedStr} = $nestedObjArray[$i];

what about this using reference variable

$finalObj = new stdClass();
$addToObject = $finalObj;
for ($i = 0; $i < count( $nestedObjArray ); $i ++) {
    $addToObject->nested = $nestedObjArray[$i];
    $addToObject = $addToObject->nested;
}

PS Correct syntax for proberty by variable is $finalObj->nested->{$nestedStr}

PPS I just wonder what purpose of this ?

What about this:

$nestedObjArray = array();
$nestedObjArray[] = new stdClass();
$nestedObjArray[] = new stdClass();
$nestedObjArray[] = new stdClass();

$finalObj = new stdClass();
$thisObj = &$finalObj;
for ($i = 0; $i < count($nestedObjArray); $i++) {
    $thisObj->nested = $nestedObjArray[$i];
    $thisObj = &$thisObj->nested;
}

Or even if you want to remove 2 of those lines, this:

$nestedObjArray = array();
$nestedObjArray[] = new stdClass();
$nestedObjArray[] = new stdClass();
$nestedObjArray[] = new stdClass();

$finalObj = new stdClass();
for ($i = 0, $thisObj = &$finalObj; $i < count($nestedObjArray); $i++, $thisObj = &$thisObj->nested) {
    $thisObj->nested = $nestedObjArray[$i];
}

What you really should do is keep a separate variable that points to the inner object. For instance...

$finalObj = new stdClass();
$innerObj = $finalObj;
for($i = 0; $i < count($nestedObjArray); $i++) {
    $innerObj->nested = $nestedObjArray[$i];
    $innerObj = $innerObj->nested;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM