The task is to traverse the tree. For these purposes I use recursion. Now you need to remove an item by its link by condition.

class Test { public function __construct() { $this->test1 = [ 'a' => 1, 'b' => [ 'd' => [ 'e' => 'test' ], ], 'c' => null, 'd' => (object)[ 'e' => 'test', ], 'f' => (object)[ 'test' => 'a', 'e' => (object)[ 'test' => 'test', ], ] ]; $this->test2 = [ 'e' => 'test', ]; $this->test3 = 'test'; $this->checkTypeRecursive($this->test1); $this->checkTypeRecursive($this->test2); $this->checkTypeRecursive($this->test3); } public function checkTypeRecursive(&$values) { if (is_array($values)) { foreach ($values as $key => $value) { $this->checkTypeRecursive($values[$key]); } } elseif (is_object($values)) { foreach ($values as $key => $value) { $this->checkTypeRecursive($values->$key); } } else { if ($values == 'test') { //Присвоение по ссылке работает. $values = 'Привет'; /** А как удалить элемент на который эта ссылка получена */ //unset($values); //Так не сработает ибо это значение. /** * Остальная логика * .... */ } } } } print_r(new Test()); 
  • What for? Do you need to pass the value by reference? if you need to get a result, return it or as a good option to throw an exception to stop the recursion for sure and not suffer from returns - Naumov
  • I do not need to interrupt the recursion or return the result. And process the whole tree. It is necessary to bypass it and remove from it all the elements that do not satisfy many conditions. I simplified the code and added a comment in the code. Остальная логика not just like that - Ninazu
  • one
    Well, so you process the value do unset in the array. Pass in the $key function and do unset($values[$key]) - Naumov
  • Although then how to deal with test3, it doesn’t have a key -_- - Ninazu

1 answer 1

Let the recursion method return true if the value passed to it matches your condition, in which case we check what it returned and if true remove the element with the unset function.

 class Test { public function __construct() { $this->test1 = [ 'a' => 1, 'b' => [ 'd' => [ 'e' => 'test' ], ], 'c' => null, 'd' => (object)[ 'e' => 'test', ], 'f' => (object)[ 'test' => 'a', 'e' => (object)[ 'test' => 'test', ], ] ]; $this->test2 = [ 'e' => 'test', ]; $this->test3 = 'test'; $this->checkTypeRecursive($this); } public function checkTypeRecursive(&$values) { if (is_array($values)) { foreach ($values as $key => $value) { if ($this->checkTypeRecursive($values[$key])) unset($values[$key]); } } elseif (is_object($values)) { foreach ($values as $key => $value) { if ($this->checkTypeRecursive($values->$key)) unset($values->$key); } } else { if ($values == 'test') return true; } } } print_r(new Test()); 

https://repl.it/CmJR/1

  • one
    Please add a link to online interpreters / compilers. repl.it/CmJR/0 - user207618 pm
  • Thanks for the comment, added - 5f0f5
  • Thank you. It helped. Although faced with another difficulty in the tests $this->test5 = (object)['test']; Extremely weird behavior - Ninazu
  • one
    Something is wrong with converting an array with numeric indices into an object, for example: $ this-> test5 = (object) ['x' => 'test']; works fine. - 5f0f5