|
|
|
| Прошу прощения у господ админов. Но мне кажется что перенесённая вами тема относится к разделу PHP. Я немного изменил вопрос, чтобы соответствовать разделу. Так что ту тему можно удалить. http://www.softtime.ru/forum/read.php?id_forum=3&id_theme=24716
Так вот.
Имеем древовидное меню, записанное в массив. Нудно его вывести, соблюдая уровни.Применим рекурсию.
<?php
//исходный массив
//children - bool - есть ли у элемента потомки
//parent - int - кто родитель элемента
$array = Array(
"1" => array("title" => "menu1", "children" => "0", "parent" => "0"),
"2" => array("title" => "menu2", "children" => "1", "parent" => "0"),
"3" => array("title" => "menu2.1", "children" => "0", "parent" => "2"),
"4" => array("title" => "menu2.2", "children" => "1", "parent" => "2"),
"5" => array("title" => "menu2.2.1", "children" => "0", "parent" => "4"),
"6" => array("title" => "menu2.2.2", "children" => "0", "parent" => "4"),
"7" => array("title" => "menu2.2.3", "children" => "0", "parent" => "4"),
"8" => array("title" => "menu2.3", "children" => "0", "parent" => "2"),
"9" => array("title" => "menu2.4", "children" => "0", "parent" => "2"),
"10" => array("title" => "menu3", "children" => "0", "parent" => "0"),
"11" => array("title" => "menu4", "children" => "0", "parent" => "0")
);
function tree($parent=0, $level=1) {
global $array;
foreach($array as $id=>$values) {
//если родитель текущего элемента не равен искомому, пропускаем его.
if($values['parent']!=$parent) continue;
//формирование префикса и вывод. (смотрите ниже)
$prefix=""; for($i=0; $i<$level; $i++) $prefix.="--";
echo "$prefix$values[title]<br>";
//если у текущего элемента есть потомки, рекурсируем
if($values['children']!=0)
tree($id, $level+1);
}
}
$arr = tree();
?>
|
Эта штука выводит
--menu1
--menu2
----menu2.1
----menu2.2
------menu2.2.1
------menu2.2.2
------menu2.2.3
|
Это не есть то что нужно.
Нужно вот что:
--menu1
--menu2
----menu2_1
----menu2_2
------menu2_2_1
------menu2_2_2
------menu2_2_3
----menu2_3
----menu2_4
--menu3
--menu4
|
как нам получить такой вывод?
у меня заработало вот так:
<?php
function tree($parent=0, $level=1) {
$array = Array(
"1" => array("title" => "menu1", "children" => "0", "parent" => "0"),
"2" => array("title" => "menu2", "children" => "1", "parent" => "0"),
"3" => array("title" => "menu2_1", "children" => "0", "parent" => "2"),
"4" => array("title" => "menu2_2", "children" => "1", "parent" => "2"),
"5" => array("title" => "menu2_2_1", "children" => "0", "parent" => "4"),
"6" => array("title" => "menu2_2_2", "children" => "0", "parent" => "4"),
"7" => array("title" => "menu2_2_3", "children" => "0", "parent" => "4"),
"8" => array("title" => "menu2_3", "children" => "0", "parent" => "2"),
"9" => array("title" => "menu2_4", "children" => "0", "parent" => "2"),
"10" => array("title" => "menu3", "children" => "0", "parent" => "0"),
"11" => array("title" => "menu4", "children" => "0", "parent" => "0")
);
foreach($array as $id=>$values) {
if($values['parent']!=$parent) continue;
$prefix=""; for($i=0; $i<$level; $i++) $prefix.="--";
echo "$prefix$values[title]<br>";
if($values['children']!=0)
tree($id, $level+1);
}
}
tree();
?>
|
Практически ничего не изменилось. Просто определение исходного массива засунуто в саму функцию. Так всё работает
А в первом варианте рекурсивно вызванные функции, как я понял, не передают управление вызвавшей, а просто самая "нижняя" из них при достижении конца завершает работу всей конструкции.
Кто-нибудь знает, что происходит? | |
|
|
|
|
|
|
|
для: neudor
(18.09.2006 в 14:35)
| | >echo "$prefix$values[title]<br>";
1. А где написано что переменные можно записывать таким образом?
2. И еще мне казалось что все то что находиться в квадратных скобках должно быть заключены в кавычках. Или можно и так? | |
|
|
|
|
|
|
|
для: Wita1y
(18.09.2006 в 18:18)
| | 1) В смысле? Можно записывать в кавычках ... только в двойных
2) То что в кв. скобках должно быть строкой ... оно итак строка, кавычки просто не там стоят | |
|
|
|
|
|
|
|
для: kasmanaft
(18.09.2006 в 20:20)
| | >В смысле? Можно записывать в кавычках ... только в двойных
В смысле что переменные вместе соединены $a$b | |
|
|
|
|
|
|
|
для: Wita1y
(18.09.2006 в 20:24)
| | Wita1y
Если вы запишите
<?php
echo "$values['title']"; //1
echo $values[title]; //2
?>
|
то получите ошибку
Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING //1
|
и для второй строчки
Notice: Use of undefined constant title - assumed 'title' //2
|
Правильно вот так:
<?php
echo "$values[title]"; //1
echo $values['title']; //2
?>
|
По поводу "соединённых" переменных.
ошибочная констукция:
<?php
echo $prefix$values['title'];
?>
|
Parse error: syntax error, unexpected T_VARIABLE, expecting ',' or ';'
|
А вот если вы запишите всё в двойных кавычках, умный PHP просто выведет переменные одну за другой без пробелов.
<?php
echo "$prefix$values[title]";
?>
|
| |
|
|
|
|
|
|
|
для: neudor
(19.09.2006 в 06:48)
| | В книги по которой я учусь такого нет(может плохо читал), но есть форум.
Большое спасибо вам. Буду знать! :-) | |
|
|
|
|
|
|
|
для: neudor
(18.09.2006 в 14:35)
| | думаю дело вот в чем:
Ссылки с глобальными и статическими переменными
Движок Zend 1, лежащий в основе PHP 4, оперирует модификаторами переменных static и
global как ссылками. Например, реальная глобальная переменная, внедренная в область
видимости функции указанием ключевого слова global, в действительности создает ссылку
на глобальную переменную. Это может привести к неожиданному поведению.
Аналогично ведет себя и выражение static. Ссылки не хранятся статично.
(код)
Этот пример демонстрирует, что при присвоении ссылки статической переменной она не
запоминается, когда вы вызываете функцию &get_instance_ref() во второй раз.
http://php.net/ru/global
|
Можно использовать $array = $GLOBALS['array']; тогда тоже будет работать | |
|
|
|
|
|
|
|
для: kasmanaft
(18.09.2006 в 20:17)
| | Решил проблему ещё вчера. Сделал немного "через одно место", но тоже заработало.
<?php
function tree($parent=0, $level=1) {
global $array;
$ret = Array();
$found = Array();
$prefix=""; for($i=0; $i<$level; $i++) $prefix.="--";
foreach($array as $id=>$values) {
if($values['parent']!=$parent) continue;
$found[serialize($values)]=$id;
}
foreach($found as $seria=>$id) {
$values = unserialize($seria);
$val = "$prefix$values[title]";
if($values['children']!=0)
$ret[$val] = tree($id, $level+1);
else
$ret[$val] = 1;
}
ksort($ret);
return $ret;
}
$arr=tree();
echo "<pre>"; print_r($arr); echo "</pre>";
?>
|
На вывод получил:
Array
(
[--menu1] => 1
[--menu2] => Array
(
[----menu2.1] => 1
[----menu2.2] => Array
(
[------menu2.2.1] => 1
[------menu2.2.2] => 1
[------menu2.2.3] => 1
)
[----menu2.3] => 1
[----menu2.4] => 1
)
[--menu3] => 1
[--menu4] => 1
)
|
это уже можно разобрать через array_walk_recursive().
kasmanaft большое спасибо за ваше решение! Работает. Теперь буду выбирать! | |
|
|
|
|
|
|
|
для: neudor
(18.09.2006 в 14:35)
| | Я тут сейчас снова за рекурсии взялся. Понял как оно работает на таком уровне:
<?
function degree($x,$y)
{
if($y)
{
return $x*degree($x,$y-1);
}
return 1;
}
echo(degree(2,4)); // выводит 16
?>
|
А у вас рекурсия где находиться? Ведь называете вы тему: "Рекурсия при обработке массива", т.е. рекурсивное вычисление факториала при обработке массива. Или я опять что-то путаю!?
neudor, покажите пожалуйста, где начинается рекурсивное вычисление. Если можно, то во втором случае, когда обработка массива находится внутри функции (тела) а не за функцией как в самом начале темы. | |
|
|
|
|
|
|
|
для: Wita1y
(19.09.2006 в 10:23)
| | Wita1y
Рекурсия - это вызов функцией самой себя. Вот и ищите в теле вызов функции с таким же названием.
Подскажу:
<?php
if($values['children']!=0)
tree($id, $level+1);
?>
|
Комментарии читайте к самому первому скрипту - там всё то же самое. | |
|
|
|
|
|
|
|
для: neudor
(19.09.2006 в 13:16)
| | Беру свои слова обратно. :-)
>автор: Wita1y (19.09.2006 в 10:23) письмо автору
>Я тут сейчас снова за рекурсии взялся. Понял как оно работает на таком уровне:
>А у вас рекурсия где находиться? Ведь называете вы тему:
>"Рекурсия при обработке массива", т.е. рекурсивное вычисление
>факториала при обработке массива. Или я опять что-то путаю!?
>neudor, покажите пожалуйста, где начинается
>рекурсивное вычисление. Если можно, то во втором случае,
>когда обработка массива находится внутри функции (тела)
>а не за функцией как в самом начале темы.
Я смотрю в код и не вижу комментариев. :-)))
Как бы устно пытаюсь разобрать ваш код, что из чего выходит. Настолько сильное внимание у меня на структура кода что даже не замечаю комментариев. Ну да ладно, с кем не бывает.
Или все такие внимательные здесь?! :-) | |
|
|
|
|