物业的递归

I have a object - let's call it $node.

This object has a property called $node->children, which essentially returns a array of child objects (nodes), in the form of node_id => NodeObject:

Array
  [1]  => Node object
  [2]  => Node object
  [3]  => Node object
  ...

These child objects are of the same type, so they too have the same property...

How can I gather all the child and grand-child node IDs for a given node?

I need to somehow walk trough the all child nodes, but I don't know how. Right now I'm stuck with array_keys($children), but it only gets me the 1st level children.

Not sure if it matters but this property comes from a magic __get method, I can't see its contents with print_r ...

function walknode($node) {
  //Do some stuff with the node here, e.g.
  echo "I am working on node $node->name<br>
";

  if (is_array($node->children)) 
    foreach ($node->children as $child)
       walknode($child);
}

walknode($basenode);

If nodes of all generations have distinct IDs, this ought to work:

$idArray = array();
$nodes = $node->children();
foreach ($nodes as $pKey => $parent) {
     array_push($idArray,$pKey);
     $childNodes = $parent->children();
     foreach ($childNodes as $cKey => $child) {
         array_push($idArray,$cKey);
     }
}

When i understand your question correctly u get a list of the keys by:

array_keys($node->children)

for iterating use

for ($node->children as $key => $value) {
  var_dump($key . ' => ' . $value);
}

Try something like the following:

function walkNodes($node, $props = array()) {

  $props[] = $node->id;

  if(isset($node->children) && is_array($node->children)){
     foreach($node->children as $child) {
        $props = walkNodes($child, $props);
     }
  }

  return $props;
}

Assign a method to the class these objects are instances of, something like hasChildren. If during iteration of array_keys($children), one of the children returns true then you have to traverse into it.

<?php

class SomeCollection {
    public $name;
    public $children = array();

    public function hasChildren()
    {
        return !empty($this->children);
    }

    public function iterate()
    {
        // process children
        foreach(array_keys($this->children) as $child) {

            // process grandchildren
            if($child->hasChildren()) {
                foreach(array_keys($child->children) as $grandchild) {
                    echo $child . ' is my child & ' .
                        $grandchild . ' is my grandchild!' . PHP_EOL;
                }
            } else  // process children without grandchildren
                echo $child . ' is my child of mine with no children of his own!';
        }
    }
}

If you want to explore some built in tools checkout the SPL Iterators