AlexZ77
Новичок
Дата регистрации:
16.10.2011 20:41:14
Сообщений: 11
Уважаемый Михаил. Есть такой вопрос. Можно ли и если да то как вывести данные в виде дерева. Например в БД есть ряд чисел:
INSERT INTO `numbers` (`id`, `number`, `enter`) VALUES
(1, 111111, 222222),
(2, 222222, 333333),
(3, 333333, 444444),
(4, 444444, 555555),
(5, 555555, 666666),
(6, 777777, 888888),
(7, 888888, 999999),
(8, 123456, 666666),
(9, 654321, 666666),
(10, 112233, 444444),
(11, 332211, 555555),
(13, 667788, 112233);
Как видно попадаются номера входимость которых является номером других. А задача состоит в том, чтобы при запросе SELECT * FROM `list` WHERE `enter` = 666666
выводилось примерно следующее:
666666
|
|--555555
| |
| |--444444
| | |
| | |--333333
| | | |
| | | |--222222
| | | |
| | | |--111111
| | |
| | |--112233
| | |
| | |--667788
| |
| |--332211
|
|--123456
|
|--654321
То есть подробное дерево всех затронутых номеров. Долго бьюсь пока не получается. Если поможете буду очень признателен.
Admin
Администратор
Дата регистрации:
27.05.2010 21:23:42
Сообщений: 3063
Примерно такой алгоритм (насколько я вообще понял задачу, конечно):
1. Получить всю таблицу (неважно, какой enter).
2. Эту таблицу разбить на 2 одномерных массива (number и enter).
3. Написать функцию, принимающую требуемый enter и отступ.
4. Передать в функцию значение (например, 666666) и пустую строку в качестве отступа. По значению определить номера элементов в массиве enter (в примере их 3).
5. Начать перебирать каждый из number (взятый по номеру enter). Если данный number так же имеется в enter, то рекурсивно вызвать данную функцию с этим number (отступ уже поставить текущий_отступ."--"
, предварительно выведя его на экран. Если его нет, то просто вывести на экран. Дальше перейти к следующему number (в первом запуске функции их всего 3).
Это только примерный алгоритм, а дальше нужно его Вам додумать.
AlexZ77
Новичок
Дата регистрации:
16.10.2011 20:41:14
Сообщений: 11
Спасибо за совет. Буду пробовать по результатам отпишусь. А ничего если в таблице около 50000 номеров. Сервер не крякнет?
Admin
Администратор
Дата регистрации:
27.05.2010 21:23:42
Сообщений: 3063
Да нет, ничего страшного не будет.
AlexZ77
Новичок
Дата регистрации:
16.10.2011 20:41:14
Сообщений: 11
Пока для меня сложная задача. Но я все равно не сдамся.Если будет возможность, напишите пожалуйста статейку, как решают подобные задачи профи. Это будет полезно для начинающих типа меня. Спасибо.
AlexZ77
Новичок
Дата регистрации:
16.10.2011 20:41:14
Сообщений: 11
Слышал, что запросов к БД в цикле следует избегать. Насколько это верно по Вашему?
Admin
Администратор
Дата регистрации:
27.05.2010 21:23:42
Сообщений: 3063
Это действительно так, поскольку цикл работает очень быстро, как следствие, возникает огромное количество запросов, идущих с большой частотой. А у любого хостинга (да и выделенного сервера тоже) есть серьёзные ограничения на количество подключений, поэтому 2-3 таких цикла одновременно (особенно, если запрос тяжёлый) и сервер может легко упасть.
AlexZ77
Новичок
Дата регистрации:
16.10.2011 20:41:14
Сообщений: 11
Вот пока результат того, что у меня получилось, следуя Вашему алгоритму. Вот код:
<?php
$db = mysql_connect("localhost", "findAlexZ", "12345"
mysql_select_db("list",$db);
mysql_query("SET NAMES cp1251"
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Древовидный вывод</title>
</head>
<body>
<?php
$result = mysql_query("SELECT `number` FROM `numbers` ORDER BY `id`",$db) or die("Error query from database: ".mysql_error());
for ($i=1; $myrow = mysql_fetch_array($result); $i++) {
$number[] = $myrow['number'];
//echo $number."<br>";
}
//echo "<br><br>";
$result1 = mysql_query("SELECT `enter` FROM `numbers` ORDER BY `id`",$db) or die("Error query from database: ".mysql_error());
for ($i=1; $myrow1 = mysql_fetch_array($result1); $i++) {
$enter[] = $myrow1['enter'];
//echo $enter."<br>";
}
$data = array_combine($number, $enter);
//echo "<pre>";
//print_r($data);
//echo "</pre>";
?>
<form action="<?php $SERVER ['SCRIPT_NAME']?>" method="get">
<input name="search" type="text" size="30">
<input name="go" type="submit" value="Поиск">
</form>
<?php
$search = $_GET['search'];
$go = $_GET['go'];
if (isset($go) && isset($search)) {
echo $search."<br>";
echo "|<br>";
echo "|--";
}
foreach ($data as $k=>$v){
if ($v == $search) {
echo $k."<br>";
//if ($new_v = array_search($k,$data)) {
//echo "| |--".$new_v."<br>";
//}
echo "|<br>";
echo "|--";
}
}
?>
</body>
</html>
А вот результат его работы после набора в форме 666666 и нажатия кнопки:
666666
|
|--555555
|
|--123456
|
|--654321
|
|--
Далее хотел развить поиск и ввел еще одно условие где $new_v (пока закомментировано). Получил результат:
666666
|
|--555555
| |--444444
|
|--123456
|
|--654321
|
|--
Как только эту проверку провожу в цикле, явно что-то не так, браузер виснет наглухо. Что я делаю не правильно, и вообще в верном ли направлении двигаюсь? И еще непонятно как не выводить последнии строчки когда уже ничего не выводится? Заранее спасибо.
Admin
Администратор
Дата регистрации:
27.05.2010 21:23:42
Сообщений: 3063
К сожалению, разобраться в чужом коде в данном случае сложнее, чем написать самому. Поэтому ищите ошибку самостоятельно. А насчёт цикла могу подсказать. Если 1 раз программа проходит, значит, она пройдёт и 1000 раз. Следовательно, всё зависит от входных значений. Посмотрите, при каком значении происходит зацикливание. Это легко сделать с помощью flush(), выводя в браузер данные прямо во время выполнения скрипта.
AlexZ77
Новичок
Дата регистрации:
16.10.2011 20:41:14
Сообщений: 11
Я ни разу ей не пользовался. В нете нашел в общих чертах что она делает, а вот как применять - ?. Не могли бы Вы показать как она применяется на простейшем каком-нибудь примере (желательно с зацикленным выводом). Спасибо за поддержку!