|
|
|
| Для любителей рекурсии и Смарти.
Есть вот такая функция
<?php
include("dbopen.php");
function ShowTree($parent_id, $lvl) {
global $link;
global $lvl;
$lvl++;
$list = array(); // массив значений для Смарти
$sql = "SELECT * FROM `modules` WHERE `pid_mod` = 26 AND `pm_id` = ". $parent_id ." AND `visib` = 1 ORDER BY `id_mod`";
$result = mysql_query($sql, $link);
if(mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$list[] = $row;
$id = $row['id_mod'];
$name = $row['name'];
ShowTree($id, $lvl);
$lvl--;
}
}
return $list;
}
echo "<pre>";
print_r(ShowTree(0,0));
echo "</pre>";
|
Выводится только родители, 0 уровень. Как вывести потомков? Где у меня ошибка? Если без разделения html и php, например, вот так:
if (mysql_num_rows($result) > 0)
{
echo("<UL>\n");
while ( $row = mysql_fetch_array($result) )
{
$id = $row["id_mod"];
echo("<LI>\n");
echo("<nobr>");
echo("<A HREF='?id=$id'>{$row["name"]}</A> \n");
echo("</nobr>");
ShowTree($id, $lvl);
$lvl--;
}
echo("</UL>\n");
}
| все выводится нормально, и родители, и потомки. Помогите, пожалуйста, второй день бьюсь. Заранее спасибо | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 09:22)
| |
<?php
include("dbopen.php");
function ShowTree($parent_id, $list)
{
global $link;
$sql = "SELECT * FROM `modules`
WHERE `pid_mod` = 26 AND `pm_id` = ". $parent_id ." AND `visib` = 1
ORDER BY `id_mod`";
$result = mysql_query($sql, $link);
$levlist = array();
while ($row = mysql_fetch_assoc($result))
levlist[] = $row;
mysql_free_result($result);
foreach($levlist as $row)
{
$list[] = $row;
$list = ShowTree($row['id_mod'], $list);
}
return $list;
}
ShowTree(0, array());
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(11.06.2008 в 10:42)
| | Теперь я передаю полученное из функции значение в шаблон. После вашего кода добавляю:
$smarty->assign('arr',$list);
$output=$smarty->fetch("menu.tpl");
и пишет ошибку: Parse error: parse error, unexpected $end in s:\home\myproject.ua\www\moduls\menu\menu2.php on line 25
25 - закрывающий тег php | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 11:44)
| | Покажите Ваш код.
Явно где-то пропущена }
Я, кстати, слегка наврал в вызове. Функция возвращает результат:
print_r(ShowTree(0, array()));
|
| |
|
|
|
|
|
|
|
для: Trianon
(11.06.2008 в 11:55)
| | Скобку добавила. Функция была не закрыта. Теперь пишет
Notice: Undefined variable: list in s:\home\myproject.ua\www\moduls\menu\menu2.php on line 21
Вот весь код:
<?php
function ShowTree($parent_id, $list){
global $link;
$sql = "SELECT * FROM `modules`
WHERE `pid_mod` = 26 AND `pm_id` = ". $parent_id ." AND `visib` = 1
ORDER BY `id_mod`";
$result = mysql_query($sql, $link);
$levlist = array();
while ($row = mysql_fetch_assoc($result)){
$levlist[] = $row;
mysql_free_result($result);
foreach($levlist as $row){
$list[] = $row;
$list = ShowTree($row['id_mod'], $list);
}
return $list;
}
}
ShowTree(0, array());
$smarty->assign('arr',$list);
$output=$smarty->fetch("menu.tpl");
?>
|
| |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 12:05)
| | Вы расстановкой скобок изрядно исказили код, нарушив логику.
Если Вам совсем невмоготу без лишних скобок - поставьте их так:
<?php
function ShowTree($parent_id, $list){
global $link;
$sql = "SELECT * FROM `modules`
WHERE `pid_mod` = 26 AND `pm_id` = ". $parent_id ." AND `visib` = 1
ORDER BY `id_mod`";
$result = mysql_query($sql, $link);
$levlist = array();
while ($row = mysql_fetch_assoc($result)){
$levlist[] = $row;
}
mysql_free_result($result);
foreach($levlist as $row){
$list[] = $row;
$list = ShowTree($row['id_mod'], $list);
}
return $list;
}
$list = ShowTree(0, array());
$smarty->assign('arr',$list);
$output=$smarty->fetch("menu.tpl");
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(11.06.2008 в 12:11)
| | А зачем здесь освобождать память mysql_free_result($result), если в конце сценария она и так освободится? Мне как-то не жалко места в памяти...
Я загрузила скрипт - и на меня смотрит чистый лист. Попробовала вот так: $list = ShowTree(0, array());
print_r($list); - распечатался массив из базы. Смарти меня где-то неправильно понимает. Что скажете? | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 12:23)
| | Просто дальше - либо отдать переменную $output в Смарти шаблон, либо просто без перехвата шаблона menu.tpl, передать полученный массив в шаблон Смарти. | |
|
|
|
|
|
|
|
для: sim5
(11.06.2008 в 12:27)
| | Передала в Смарти. Странно, но выводится все в один столбик - и родители, и потомки, вот так:
1 родитель
потомок
потомок
2 родитель
потомок
потомок
и так дальше. Не сработала рекурсия!!!
Интересно уже стало, а вообще такое в природе возможно? Чтобы через Смарти передавать рекурсию? | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 12:30)
| | Нельзя передать в Смарти рекурсию, в шаблон передается просто массив, и если этот массив многомерный, другими словами, учитывает уровни вложения категорий, то его просто нужно правильно разложить в шаблоне. Иначе в функцию запроса к базе, добавить уровень вложения категорий, уже опираясь на который, разложить массив в шаблоне. | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 12:23)
| | Приведите краткий пример (пусть даже без БД) в котором конструкция
$smarty->assign('arr',$list);
$output=$smarty->fetch("menu.tpl");
|
выведет нечто похожее на то, что Вам надо. Буквально на три-пять строк.
И приведите, пожалуйста,структуру таблицы.
дальше можно будет думать, как помочь. | |
|
|
|
|
|
|
|
для: Trianon
(11.06.2008 в 12:33)
| | Краткий пример здесь не получится. Привожу длинный и некраткий, как я делаю:
Есть шаблон index.tpl, к которому подключается menu.tpl вот так: {include file="menu.tpl"}
index.tpl выводится с помощью index.php: $output=$smarty->fetch("index.tpl");
print $output;
Код menu.tpl:
<div class = "suckerdiv">
{if !empty($arr)}
<ul id="suckertree1">
{foreach from=$arr item=row}
<LI>
<nobr><A HREF='?id={$row.id_mod}' class="mainmenu">{$row.name}</A></nobr>
</LI>
{/foreach}
</UL>
{/if}
</div>
|
В свою очередь menu.tpl обрабатывается той самой рекурсивной функцией. Подключаются к основному шаблону стили и в итоге должно получиться вот такое: в столбик - родители, наводишь указатель - справа вываливаются потомки (это с помощью JS), а у меня сейчас все в одном столбике.
Структура таблицы такая:
id_mod - id модуля
pm_id - id родителя модуля в меню
pid_mod - родитель для модуля в общей структуре сайта (вся страница делится на menu,left,content, right)
name - название модуля
index_filename - индекс-файл, через который модуль вызывается
tpl - название файла шаблона
stl - название файла стиля
descr - описание модуля
visib - подключен модуль или нет | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 12:51)
| | $smarty->fetch перехватывает шаблон вместо вывода его на экран, при этом он будет обработан, и переменная которой присвоен результат работы этого шаблона, содержит готовый HTML-код. Можно конечно теперь echo или print, но к чему тогда шаблоны? Там где необходимо теперь вывести код меню, нужно просто указать, если это в index.tpl, то, например:
$smarty->assign("menu", $output); //передали результат в шалон index.tpl
//а в index.tpl выводим где-то в нужном месте
{$menu}
Или в этом месте нужно делать подключение шаблона menu.tpl, который и будет обрабатывать переданную ему перменную {$arr}:
{if $arr}
раскладываем массив
{/if}
Обход массива должен учитывать структуру вашего меню, а она в свою очередь должна подчинятся уровню вложений категорий возвращаемых из рекурсии. Можно в рекурсивном запросе описать непосредствено элементы меню и порядок их вложения, в зависимоти от уровня вложения категорий, и в готовом уже виде передать это в шаблон. | |
|
|
|
|
|
|
|
для: sim5
(11.06.2008 в 13:19)
| | В menu.php получаю данные из функции и направляю их в шаблон menu.tpl, перехватываю результат:
$list = ShowTree(0, array());
$smarty->assign('arr',$list);
$output=$smarty->fetch("menu.tpl");
В index.php подключаю индекс-файл модуля меню и передаю результат работы menu.php:
include("moduls/menu/menu2.php");
$smarty->assign("menu", $output);
$out=$smarty->fetch("index.tpl");
print $out;
Дальше в шаблоне index.tpl вывожу перехваченные данные в отдельную ячейку:
<td>
{if $arr}
{include file="menu.tpl"}
{/if}
</td>
И все равно меню выводится в один столбец. | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 14:21)
| | То что вы передали так, это так и надо делать, если пользоваться шаблонами. Но от этого, вложений категорий не появиться, проблема этого не в способе подключения.
Лучше описать сами элементы меню (UL, LI, A) в функции ShowTree, при этом возвращаемое значение из функции будет равно уже готовому меню, останется только подключить его в шаблоне без обхода. У вас простое меню, поэтому не придется его править, так как его элементы будут у вас вложены в любом случае в контейнер DIV. Если ID этого контейнера будет равно, например, menu, то в CSS вы сможете определить положение и вид для всех его элементов.
Что касается "все в один столбик", то, если вложение ваших категорий не превышает 2 (у каждого родителя один потомок), то достаточно будет проверять в функции ShowTree() значение pm_id, и если оно равно 0, то вы описываете корневой элемент меню, если нет, то вложенный в родителя элемент меню. | |
|
|
|
|
|
|
|
для: sim5
(11.06.2008 в 14:45)
| | Зачем описывать в ShowTree элементы меню (UL, LI, A) и делать уже изначально готовое меню со всеми обходами, а потом передавать эту смесь php и html в шаблон, когда весь смысл этих мучений - разделить php и html?
Приведите пример, как проверять в функции ShowTree() вложения. | |
|
|
|
|
|
|
|
для: Лена
(11.06.2008 в 15:09)
| | Просто потому, что в этой функции проще будет описать все элементы меню - меню у вас простое, внешней правки его будет достаточно с помощью CSS. JS же в меню служит, скорее всего, для управления видимостью его элементов, работая опять таки со стилями его. Применение шаблонов, совсем не означает, что нужно забыть об обработке данных там, где это сделать выгоднее, чтобы потом усложнять задачу в шаблоне. Если же вы хотите раскладывать полученный масиив в шаблоне, то проверяйте значание родителя во время уже цикла Смарти - если рано 0, то это верхний уровень, значит: UL LI A, если нет, то следуя HTML коду меню, прописывать вложение элемента второго уровня.
Я не обладаю способностями Макаренко, для меня лучше "один раз потрогать, чем сто раз услышать"), поэтому, если будут затруднения - вышлите мне дамп таблицы и сам код меню, я приготовлю все у себя. | |
|
|
|