Во-первых, вы должны положить ваши помощники за пределами ваших контроллеров :)
больше к point: чтобы понять рекурсию, она помогает пройти шаг за шагом, и когда вы доберетесь до рекурсии, скажем, предположим, что это делает то, что должно потом вернуться туда позже.
Начнем так:
/**
* Returns the children for a given parent
* @param int $parentId
* @return array
*/
public function getChildren($parentId){
$allChildrenArray = array();
$children = DB::table('myTable')->where('parent',$parentId)->get();
foreach ($children as $child) {
array_push($allChildrenArray, array($child->slug, $child->id));
// Here should be the recursion later
}
// var_dump($allChildrenArray); displays a proper array
return $allChildrenArray;
}
Теперь, если вы посмотрите на эту функцию, вы увидите, что она работает на первом уровне. Легко сказать, что при просмотре детей данного родителя вам нужно будет получить этих потомков, если вы захотите добавить рекурсию.
/**
* Returns the children recursively for a given parent
* @param int $parentId
* @return array
*/
public function getChildren($parentId){
$allChildrenArray = array();
$children = DB::table('myTable')->where('parent',$parentId)->get();
foreach ($children as $child) {
array_push($allChildrenArray, array($child->slug, $child->id));
// get descendants of child
$furtherDescendants = $this->getChildren($child->id);
// add them to current list
foreach ($furtherDescendants as $desc) {
$allChildrenArray[] = $desc; // or use arraypush or merge or whatever
}
}
// var_dump($allChildrenArray); displays a proper array
return $allChildrenArray;
}
Теперь то, что происходит в том, что, когда вы достигнете первого ребенка новый запуск функции GetChildren начнется Ид этого ребенка в качестве родительского идентификатора. Если их нет, тогда он вернет пустой массив, в противном случае он добавит информацию для этого ребенка, а затем запустит новый прогон для идентификатора внука в качестве родительского идентификатора и ...
Вы можете вероятно, сохраните некоторую память, если вы пройдете массив вдоль, но в этом случае вам нужно сделать это как ссылку. Также тогда, когда вы вызовете этот метод в первую очередь, вам нужно передать переменную в качестве ввода, который будет заполнен.
/**
* Returns the children recursively for a given parent
* @param int $parentId
* @param &array $children
*/
public function getChildren($parentId, &$allChildrenArray) {
$children = DB::table('myTable')->where('parent',$parentId)->get();
foreach ($children as $child) {
array_push($allChildrenArray, array($child->slug, $child->id));
// get descendants of child
$this->getChildren($child->id, $allChildrenArray);
}
// var_dump($allChildrenArray); displays a proper array
return; // nothing to return, children info added to variable passed by reference
}
...
$kids=array();
$this->getChildren($parentId, $kids);
var_dump($kids)
Просто убедитесь, что вы не смешиваете два разных решения.
Условие выхода будет иметь место, если у данного родителя нет детей. В этом случае foreach не запускается, поэтому дальнейших рекурсивных вызовов не будет. Однако это означает только выход из этой ветви.
Самый простой способ понять это - пройти все шаги вручную на листе бумаги. «Я получаю« null », потому что вы ничего не возвращаете в случае, если' sizeof ($ children)> 0'. Вы также не используете результат вызова MyController :: getChildren. – zerkms
Но если 'sizeof ($ children)> 0', если есть дети, я обновляю значение' $ allChildrenArray'. И затем я просто перезапускаю то же самое с обновленным значением массива children и обновленным эталоном. Что я должен вернуть? – Yako
«Я обновляю значение $ allChildrenArray» и ничего не делаю с ним. Вы изменили переменную, и что? Это не волшебное изменение в том месте, откуда вы его передали. – zerkms