ГОЛЯМ Проблем: Дървовидна структура на под-категории

xlebabarov

Registered
Здравейте. От няколко дена се опитвам да се справя с добавянето на категории и подкатегории. Имам следната таблица:

Код:
CREATE TABLE IF NOT EXISTS `kategorii` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ime` varchar(225) NOT NULL,
  `sub` int(11) NOT NULL DEFAULT '0',
  `subbr` int(11) NOT NULL DEFAULT '0',
  `red` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=25 ;

--
-- Дъмп (схема) на данните в таблицата `kategorii`
--

INSERT INTO `kategorii` (`id`, `ime`, `sub`, `subbr`, `red`) VALUES
(1, 'Телефони', 0, 0, 1),
(2, 'PC компоненти', 0, 0, 2),
(3, 'Преносими компютри', 0, 0, 3),
(4, 'Мобилни устройства', 0, 0, 4),
(5, 'Техника', 0, 0, 5),
(6, 'Бяла техника', 0, 0, 6),
(7, 'Други', 0, 0, 7),
(8, 'Apple', 1, 1, 1),
(9, 'Asus', 1, 1, 2),
(10, 'BlackBerry', 1, 1, 3),
(11, 'HTC', 1, 1, 4),
(12, 'LG', 1, 1, 5),
(13, 'Motorola', 1, 1, 6),
(14, 'Nokia', 1, 1, 7),
(15, 'Телевизори', 1, 5, 1),
(16, 'Конзоли', 1, 5, 2),
(17, 'Видео-DVD', 1, 5, 3),
(18, 'BR Audio', 1, 5, 4),
(19, 'Аудио Камери/Фото', 1, 5, 5),
(20, '3GS', 2, 8, 1),
(21, '3G', 2, 8, 2),
(22, '2G', 2, 8, 3),
(23, '1G', 2, 8, 4);

Идеята на таблицата:

ime - името на категорията
sub - това поле играе 2 роли. Ако е 0, то полето не е под категория, а главна. Ако е 1, то полето е подкатегория от 1-ви ред (суб-категория). Ако е 2, то полето е подкатегория от 2-ри ред (суб-суб-категория), ако е n, то полето е подкатегория от n-ти ред ((nxсуб-)категория). Надявам се разбрахте.
subbr - Ако sub>0 (т.е. е подкатегория), то тук се записва ID-то на горната категория
red - тази променлива я използвам, за да подреждам всички категории от един ред

Да приемем, че сте разбрали обяснението ми. Сега искам да покажа всички категории в този вид:

Код:
<select name="cat">
<option value="1">Телефони</option>
<option value="8">»Apple</option>
<option value="20">»»3GS</option>
<option value="21">»»3G</option>
<option value="22">»»2G</option>
<option value="23">»»1G</option>
<option value="9">»Asus</option>
<option value="10">»BlackBerry</option>
<option value="11">»HTC</option>
<option value="12">»LG</option>
<option value="13">»Motorola</option>
<option value="14">»Nokia</option>
<option value="2">PC компоненти</option>
<option value="3">Преносими компютри</option>
<option value="4">Мобилни устройства</option>
<option value="5">Техника</option>
<option value="15">»Телевизори</option>
<option value="16">»Козоли</option>
<option value="17">»Видео DVD</option>
<option value="18">»BR Audio</option>
<option value="19">»Аудио Камери/Фото</option>
<option value="6">Бяла техника</option>
<option value="7">Други</option>
</select>

За целта създадох това:

Код:
echo('<select name="cat">
');

$izberi_posledno_nivo = mysql_query("SELECT `subbr`
FROM `kategorii`
ORDER BY `kategorii`.`subbr` DESC 
LIMIT 1;") or die1(mysql_error(), 1);
while($krai1 = mysql_fetch_array($izberi_posledno_nivo)){
$krai = $krai1['subbr'];
}

echo($krai);

for($i=0; $i<=$krai; $i++){
if($i==0){
$izberivsi4kiotparvivred = mysql_query("SELECT *
FROM `kategorii`
WHERE `sub` =".$i."
ORDER BY `red` ASC ") or die1(mysql_error(), 2);

while($r1=mysql_fetch_array($izberivsi4kiotparvivred)){
echo('<option value="'.$r1['id'].'">'.$r1['ime'].'</option>');
}
}else{
$izberivsi4kiotparvivred = mysql_query("SELECT *
FROM `kategorii`
WHERE `sub` =".$i."
ORDER BY `red` ASC ") or die1(mysql_error(), 2);

while($r1=mysql_fetch_array($izberivsi4kiotparvivred)){
for($z=1;$z<=$i;$z++){$znak.='»';}
echo('<option value="'.$r1['id'].'">'.$znak.$r1['ime'].'</option>
');
$znak='';
}
}
}

echo('</select>');

Но скрипта го изкарва ето така:

Код:
<select name="cat">
<option value="1">Телефони</option><option value="2">PC компоненти</option><option value="3">Преносими компютри</option><option value="4">Мобилни устройства</option><option value="5">Техника</option><option value="6">Бяла техника</option><option value="7">Други</option><option value="8">»Apple</option>

<option value="15">»Телевизори</option>
<option value="9">»Asus</option>
<option value="16">»Конзоли</option>
<option value="10">»BlackBerry</option>
<option value="17">»Видео-DVD</option>
<option value="11">»HTC</option>
<option value="18">»BR Audio</option>
<option value="19">»Аудио Камери/Фото</option>
<option value="12">»LG</option>

<option value="13">»Motorola</option>
<option value="14">»Nokia</option>
<option value="20">»»3GS</option>
<option value="21">»»3G</option>
<option value="22">»»2G</option>
<option value="23">»»1G</option>

Предложете как да го направя, че да ги извежда така:

Код:
<select name="cat">
<option value="1">Телефони</option>
<option value="8">»Apple</option>
<option value="20">»»3GS</option>
<option value="21">»»3G</option>
<option value="22">»»2G</option>
<option value="23">»»1G</option>
<option value="9">»Asus</option>
<option value="10">»BlackBerry</option>
<option value="11">»HTC</option>
<option value="12">»LG</option>
<option value="13">»Motorola</option>
<option value="14">»Nokia</option>
<option value="2">PC компоненти</option>
<option value="3">Преносими компютри</option>
<option value="4">Мобилни устройства</option>
<option value="5">Техника</option>
<option value="15">»Телевизори</option>
<option value="16">»Козоли</option>
<option value="17">»Видео DVD</option>
<option value="18">»BR Audio</option>
<option value="19">»Аудио Камери/Фото</option>
<option value="6">Бяла техника</option>
<option value="7">Други</option>
</select>

Надявам се, сте ме разбрали. Ако не сте разбрали нещо, питайте :?:
 
GaTio2 каза:
пробвай вместо ASC DESC размени и пробвай

Така само ще обърна редовете. Ще започне да ми показва заявките от втори ред в началото (суб-суб), след което ще следват от първи ред (суб-) и най-накрая ще са тези от нулев (коети не са подкатегории).

Това, което аз искам да постигна, е да показва Главната кагегория -> нейните суб-категории->техните суб-суб-категории и т.н. докато се свършат всички подкатегории :?
 
В зависимост от под категориите, няколко цикъла и запазваш всичко по следния начин $array = { [категория]=> { [под категория] => { ... }}
1 масив с главните директории, всяка от които е ключ към нов вграден масив с под кагегории и т.н

После колкото са вградените масиви толкова foreach-a и си готов. За по лесно не ми идва идея :(
 
g9m29 каза:
В зависимост от под категориите, няколко цикъла и запазваш всичко по следния начин $array = { [категория]=> { [под категория] => { ... }}
1 масив с главните директории, всяка от които е ключ към нов вграден масив с под кагегории и т.н

После колкото са вградените масиви толкова foreach-a и си готов. За по лесно не ми идва идея :(

Проблема идва от там, че не знам колко под-под-под-...категории ще има. (т.е. един вид имам n на брой подкатегории) :shock:

Става въпрос за изработването на админ панел на сайт, който правя за една фирма. За това не знам колко подкатегории ще има
 
Ми щом ще са N, преди да почнеш да правиш под-под-под ще ги пребройш и проблема е решен!
Няколко вариянта:
Имаш COUNT в заявката, само че ще бави при по голяма заявка.
Имаш mysql_num_rows() което ти връща готов числов тип int
Имаш и count() ако искаш да ги преброяваш от масива
 
g9m29 каза:
Ми щом ще са N, преди да почнеш да правиш под-под-под ще ги пребройш и проблема е решен!
Няколко вариянта:
Имаш COUNT в заявката, само че ще бави при по голяма заявка.
Имаш mysql_num_rows() което ти връща готов числов тип int
Имаш и count() ако искаш да ги преброяваш от масива

Ако погледнеш кода, който съм дал, именно това съм направил:

Код:
$izberi_posledno_nivo = mysql_query("SELECT `subbr`
FROM `kategorii`
ORDER BY `kategorii`.`subbr` DESC
LIMIT 1;") or die1(mysql_error(), 1);
while($krai1 = mysql_fetch_array($izberi_posledno_nivo)){
$krai = $krai1['subbr'];
}

$krai ми е равно на последното "ниво" (в случая с тези данни по-горе, то $krai=8). Но ми ги изкарва по този начин, горе... :idea:
 
Нещо неможах да ти проследя мисълта в PHP кода.
Датабазата ти е много странно структурирана (буквално).

Код:
$sql = mysql_query("SELECT * FROM `cat` WHERE `sub` = '0' ORDER BY `id` ASC ");
while ($assoc = mysql_fetch_array($sql, MYSQL_ASSOC)) {
    $subID = $assoc['id'];
    echo "Категорията е: ".$assoc['ime']."<br />";

    $sql = mysql_query("SELECT `sub` FROM `cat` WHERE `subbr` = '$subID' AND `sub` > 0");
    $subs = mysql_num_rows($sql);

    if ($subs > 0) {
        $g = "Под-";
        for ($i = 1; $i <= $subs; $i++) {
            $sql = mysql_query("SELECT `subs` FROM `cat` WHERE `subbr` = '$subID' AND `sub` = $i");
            while ($assoc = mysql_fetch_array($sql)) {
                echo $g."категорията е: ".$assoc['name']."<br />";
            }
                echo "<hr />";
            $g = $g."под-";
        }
    } else {
        echo 'Няма под-категории!';
    }
}

Ако нямам грешка в писането, би трябвало да изкара:

Категория:
Под-категория
Под-категория
Под-категория
-----------------
Под-под-категория
Под-под-категория
Под-под-категория
Под-под-категория
-----------------
Под-под-..n-категория
Под-под-..n-категория
Под-под-..n-категория
Под-под-..n-категория


Направил съм го така, за да разгледаш резултатите и начина, по който ги изкарвам.
 
Не става.... наистина нищо не става... пробвах да поставя резултатите в масив - не става и не става
dash1.gif
dash1.gif
dash1.gif


Дайте идеи, моля Ви! Искам да изкарам резултатите така:

Код:
<select name="cat">
<option value="1">Телефони</option>
<option value="8">»Apple</option>
<option value="20">»»3GS</option>
<option value="21">»»3G</option>
<option value="22">»»2G</option>
<option value="23">»»1G</option>
<option value="9">»Asus</option>
<option value="10">»BlackBerry</option>
<option value="11">»HTC</option>
<option value="12">»LG</option>
<option value="13">»Motorola</option>
<option value="14">»Nokia</option>
<option value="2">PC компоненти</option>
<option value="3">Преносими компютри</option>
<option value="4">Мобилни устройства</option>
<option value="5">Техника</option>
<option value="15">»Телевизори</option>
<option value="16">»Козоли</option>
<option value="17">»Видео DVD</option>
<option value="18">»BR Audio</option>
<option value="19">»Аудио Камери/Фото</option>
<option value="6">Бяла техника</option>
<option value="7">Други</option>
</select>
 
Не ги слагай в масив, опитай горния вариант ( кода който дадох ), само че ги изкарвай от <option> няма как да не работи.
 
ОК, пробвах по твоя начин:

Ето го и файла:

Код:
<?php
mysql_connect("localhost", "*", "*") or die(mysql_error());
mysql_select_db("desitabg") or die(mysql_error());	
mysql_query('SET NAMES cp1251');
mysql_query('SET CHARACTER SET cp1251_general_ci');

 $sql = mysql_query("SELECT * FROM `kategorii` WHERE `sub` = '0' ORDER BY `id` ASC ");
while ($assoc = mysql_fetch_array($sql, MYSQL_ASSOC)) {
    $subID = $assoc['id'];
    echo "Kategoriqta e: ".$assoc['ime']."<br />";

    $sql = mysql_query("SELECT `sub` FROM `kategorii` WHERE `subbr` = '$subID' AND `sub` > 0");
    $subs = mysql_num_rows($sql);

    if ($subs > 0) {
        $g = "sub-";
        for ($i = 1; $i <= $subs; $i++) {
            $sql = mysql_query("SELECT `subs` FROM `kategorii` WHERE `subbr` = '$subID' AND `sub` = $i");
            while ($assoc = mysql_fetch_array($sql)) {
                echo $g."kategoriqta e: ".$assoc['name']."<br />";
            }
                echo "<hr />";
            $g = $g."sub-";
        }
    } else {
        echo 'Nqma podkategorii!';
    }
}	
	?>

Код:
Kategoriqta e: Телефони

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\desita\test.php on line 8
 
Добре... реших да погледна колегите програмисти от чужбина какво мислят по въпроса и намерих следното мнение, което мисля, че е решение на проблема ми:

http://www.ozzu.com/programming-forum/php-mysql-multi-level-tree-categories-t70918.html#p391072

от цялата работа не успях да разбера какво прави този ред:

Код:
$pos = ($pos?$pos:null);

Някой може ли да разясни малко?
 
$pos?$pos:null това е еквивалент на
Код:
if ($pos) {
 $pos;
} else {
null
}
 
g9m29 каза:
$pos?$pos:null това е еквивалент на
Код:
if ($pos) {
 $pos;
} else {
null
}

А къде е проблема на твоя код?
 
ПП, Мисля че имаше изпуснати 2 '
Код:
 <?php
mysql_connect("localhost", "*", "*") or die(mysql_error());
mysql_select_db("desitabg") or die(mysql_error());   
mysql_query('SET NAMES cp1251');
mysql_query('SET CHARACTER SET cp1251_general_ci');

 $sql = mysql_query("SELECT * FROM `kategorii` WHERE `sub` = '0' ORDER BY `id` ASC ");
while ($assoc = mysql_fetch_array($sql, MYSQL_ASSOC)) {
    $subID = $assoc['id'];
    echo "Kategoriqta e: ".$assoc['ime']."<br />";

    $sql = mysql_query("SELECT `sub` FROM `kategorii` WHERE `subbr` = '$subID' AND `sub` > '0'");
    $subs = mysql_num_rows($sql);

    if ($subs > 0) {
        $g = "sub-";
        for ($i = 1; $i <= $subs; $i++) {
            $sql = mysql_query("SELECT `subs` FROM `kategorii` WHERE `subbr` = '$subID' AND `sub` = '$i'");
            while ($assoc = mysql_fetch_array($sql, MYSQL_ASSOC)) {
                echo $g."kategoriqta e: ".$assoc['name']."<br />";
            }
                echo "<hr />";
            $g = $g."sub-";
        }
    } else {
        echo 'Nqma podkategorii!';
    }
}   
   ?>
 
Намерих грешкката...
 
След поправка на грешката, кода показва това:

Kategoriqta e: Телефони
sub-kategoriqta e: Apple
sub-kategoriqta e: Asus
sub-kategoriqta e: BlackBerry
sub-kategoriqta e: HTC
sub-kategoriqta e: LG
sub-kategoriqta e: Motorola
sub-kategoriqta e: Nokia
______________________________________________________________
______________________________________________________________
______________________________________________________________
______________________________________________________________
______________________________________________________________


И до там... :idea:
 
$sql = mysql_query("SELECT * FROM `kategorii` WHERE `sub` = '0' ORDER BY `id` ASC ");
while ($assoc = mysql_fetch_array($sql, MYSQL_ASSOC)) {
$subID = $assoc['id'];
echo "Kategoriqta e: ".$assoc['ime']."<br />";

$sql = mysql_query("SELECT `sub` FROM `kategorii` WHERE `subbr` = '$subID' AND `sub` > '0'");
$subs = mysql_num_rows($sql);

if ($subs > 0) {
$g = "sub-";
for ($i = 1; $i <= $subs; $i++) {
$sql = mysql_query("SELECT * FROM `kategorii` WHERE `subbr` = '$subID' AND `sub` = '$i'");
while ($assoc = mysql_fetch_array($sql, MYSQL_ASSOC)) {
echo $g."kategoriqta e: ".$assoc['ime']."<br />";
}
echo "<hr />";
$g = $g."sub-";
}
} else {
echo 'Nqma podkategorii!';
}
}
 

Back
Горе