Написал функцию, которая осуществляет собственно sql-рекурсию, вызывая ваш callback на каждой итерации. Применять можно для таблиц всяких рубрикаторов, вложенность которых построена на т.н. parentID.
Поддерживаются дополнительные переменные, которые будут передаваться в callback-функцию. Сама функция весьма хитро жонглирует аргументами, давая возможность передать в sqlRecursion() любое количество дополнительных аргументов (после обязательных).
Единственное ограничение на sql-запрос: Ключевое поле ID должно идти первым, а родительский ID — последним.
/**
* Recursively executes sql query by parentID
*/
function sqlRecursion($sprintf, $res, $callback, $level=0) {
$ordering = 0; $a = func_get_args();
$callbackParams = array_splice($a, 4);
$tmp = qry($q=call_user_func_array('sprintf', $sprintf), $res);
while($row = mysql_fetch_assoc($tmp)) {
$tm = $callbackParams;
array_unshift($tm, $row, ++$ordering, $level);
// callback($row, $ordering, $some_vars)
call_user_func_array($callback, $tm);
// replaces parent id in sql structure $sprintf
array_splice($sprintf,count($sprintf)-1,1,reset($row));
$recParams = array($sprintf, $res, $callback, $level+1);
array_splice($recParams, count($recParams),0,$callbackParams);
call_user_func_array('sqlRecursion', $recParams);
}
}
Пример использования прилагается.
// @example
function myCallback($row, $ordering, $level, $var1, $var2) {}
sqlRecursion(array(
"select ID, %s from %s where parent = %d",
// ID (keyfield) must be first,
// parent id must be last in sql query
'myField', 'myTable', 31337
),
$mysqlResourceLink, 'myCallback', 0, $var1, $var2
);