Guillaume Fe
Guillaume Fe

Reputation: 369

Removing a deeply nested object property using an array of object property names

Original Title: How can I dynamically enclose attributes in variable before actual object call

Generic Question

How can I create $target in a way that it can be correctly var_dumped?

    $type = 'lib';
    $target = 'test->test2';

    var_dump($GLOBALS[$this->context]->$type->test->test2);//returns object(test\test2)#15 (0) { } 

    var_dump($GLOBALS[$this->context]->$type->{$target}); //returns NULL ( Undefined property: stdClass::$test->test2 )

More Examples

this (below) works like a charm

   $target = 'test';
   $type = new \stdClass();
   $type->test = new \stdClass();
   $type->test->test2 = 5;
   var_dump($type->$target); // Returns object(stdClass)#24 (1) { ["test2"]=> int(5) } 

this (below) does not :

   $target = 'test->test2';
   $type = new \stdClass();
   $type->test = new \stdClass();
   $type->test->test2 = 5;
   var_dump($type->$target);// Returns NULL (Notice: Undefined property: stdClass::$test->test2)

Real Case :

I want to unset $GLOBALS[$this->context]->$type->test->test2

My first though :

public function unSys($type, $thing) {

//$type = 'lib';
//$thing = 'test/test2';

$parts = explode('/',$thing);
$final = implode('->',$parts);
unset($GLOBALS[$this->context]->$type->{$final});

}

What I've tried after that :

...

$parts = explode('/',$thing);
$target = $GLOBALS[$this->context]->$type;

        foreach ($parts as $value) {
            $target = $target->$value;
        }

unset($target);
var_dump($GLOBALS[$this->context]->$type->test->test2);//still exist

...

I also tried passing by reference without luck :

...
$target = &$GLOBALS[$this->context]->$type;
...

Upvotes: 0

Views: 1003

Answers (1)

Tim G
Tim G

Reputation: 1822

Guillaume,

I think you're wanting to use an array of property names that represent a chain of nested objects to remove the last nested object property.

See if this code makes sense and solves your problem.

<?PHP

$GLOBALS['tmp'] = (object)array( 'lib' => (object)array( 'test' => (object)array( 'test2' => (object)array()) ) );
var_dump( $GLOBALS['tmp'] );

$context = 'tmp';

$type = 'lib';
$thing = 'test/test2';

$parts = explode('/',$thing);
$target = $GLOBALS[$context]->$type;
var_dump( $target );
var_dump( $parts );
$itemToUnset = array_pop( $parts );

foreach ($parts as &$value) {
    $target =& $target->$value;
}

unset( $target->{$itemToUnset} );
var_dump( $GLOBALS['tmp'] );

// test 2 is not set
var_dump( $GLOBALS['tmp']->lib->test->test2 );

The output looks like this:

object(stdClass)[4]
public 'lib' => 
    object(stdClass)[3]
        public 'test' => 
          object(stdClass)[2]
            public 'test2' => 
              object(stdClass)[1]
                ...
object(stdClass)[3]
public 'test' => 
    object(stdClass)[2]
        public 'test2' => 
        object(stdClass)[1]

array (size=2)
0 => string 'test' (length=4)
1 => string 'test2' (length=5)

object(stdClass)[4]
public 'lib' => 
    object(stdClass)[3]
        public 'test' => &
        object(stdClass)[2]

Notice: Undefined property: stdClass::$test2

Upvotes: 1

Related Questions