Я работаю над проектом, в котором есть категории, подкатегории, подкатегории и т. д. Пользователь может их создавать. Я хочу отобразить их на столе. Я использую эту функцию, но возврат дает мне только категории родителей (parent_id = 0). В нем отсутствуют подкатегории, а подкатегории... Если я помещаю var_dump, он показывает мне, что конкатенация работает, но когда функция находит другого родителя категории, теряет другие данные. Что я делаю не так, помогите.
Я хочу вернуть переменную, содержащую все категории и подкатегории.
function categoryTree($catsSubcats = "", $parent_id = 0, $sub_mark = ""){ var_dump($catsSubcats);
$stmt = Conexion::conectar()->prepare("SELECT * FROM categorias_compra WHERE parent_id = $parent_id");
$stmt -> execute();
$respuesta = $stmt -> fetchAll();
if ($respuesta){
foreach($respuesta as $key => $value){
$catsSubcats = $catsSubcats . $sub_mark.$value['nombre'].'<br>';
categoryTree($catsSubcats, $value['id'], $sub_mark.str_repeat(' ', 5));
}
return $catsSubcats;
}
}
Вы не используете результат рекурсивного вызова. Вы хотели добавить это к выходной строке?
Нравится $catsSubcats .= categoryTree(...)
Я хочу добавить все категории и подкатегории в одну строку вывода.
Большое спасибо "Don't Panic"... да, это то, что я хотел
Не по теме: ваш код уязвим для SQL-инъекций. Если вы уже пошли и использовали функцию prepare, то вместо того, чтобы помещать $parent_id непосредственно в строку, используйте заполнитель ? и передайте переменную через функцию execute.






Вы не используете возвращаемое значение в рекурсии. Вероятно, вы хотите что-то вроде этого:
function categoryTree($parent_id = 0, $sub_mark = ""){
$catsSubcats='';
$stmt = Conexion::conectar()->prepare("SELECT * FROM categorias_compra WHERE parent_id = $parent_id");
$stmt -> execute();
$respuesta = $stmt -> fetchAll();
if ($respuesta){
foreach($respuesta as $key => $value){
$catsSubcats .= $sub_mark.$value['nombre'].'<br>';
$catsSubcats .= categoryTree($value['id'], $sub_mark.str_repeat(' ', 5));
}
}
return $catsSubcats;
}
Основная проблема заключается в том, что результат рекурсивного вызова не используется, но похоже, что если вы добавите его к строке, вы получите много повторений.
Я думаю, вам не нужно передавать основную строку рекурсивному вызову. Это то, что вызовет повторные результаты. Вам нужно добавить только результат рекурсивного вызова, а не этот результат плюс все, что у вас уже было на тот момент.
Кроме того, если вы рекурсивно передаете подготовленный оператор, вы должны иметь возможность повторно использовать его вместо повторной подготовки одного и того же.
Я не могу проверить это, но я думаю, что это будет работать лучше.
function categoryTree($parent_id = 0, $sub_mark = "", $stmt = null) {
if (!$stmt) {
// only prepare the first time, then pass the prepared statement to subsequent calls
$stmt = Conexion::conectar()->prepare("SELECT * FROM categorias_compra WHERE parent_id = ?");
}
// bind $parent_id to the ? placeholder in the prepared statement
$stmt->execute([$parent_id]);
$respuesta = $stmt->fetchAll();
// initialize the result of each call to an empty string
$catsSubcats = "";
if ($respuesta) {
// you can also move this before the loop so it only has to execute once
$sub_mark .= str_repeat(' ', 5);
foreach ($respuesta as $key => $value) {
$catsSubcats .= $sub_mark.$value['nombre'].'<br>';
$catsSubcats .= categoryTree($value['id'], $sub_mark, $stmt);
}
}
// always return a string
return $catsSubcats;
}
Вы ожидаете, что эта функция будет записывать данные в вашу таблицу? Нет запросов
INSERTилиUPDATE, и неясно, чего вы пытаетесь достичь