ďťż

[php, mysql] Relacja wiele do wielu + dynamiczne generowanie checkboxów

       

Podstrony


telcocafe

Cześć :)

Robię sobie stronkę, właściwie dla sportu, ale może też do portfolio. Natknąłem się na problem, którego nie mogę rozwiązać:

Stronka zawiera bazę danych filmów, z pełną edycją wszelkich wpisów. Nas interesują 3 tabele, w uproszczeniu:

Tabela "filmy": id, tytuł - zawiera dane o filmie
Tabela "tagi": id, nazwa_tagu - zawiera edytowalne tagi typu: horror, dramat, komedia, fantasy
Tabela "tagi_filmy": id, id_filmu, id_tagu - zbiera dane z obu powyższych tabel

Czyli relacja wiele do wielu (z uwagi na możliwość dodania wielu tagów do jednego filmu). Na stronie pozwalającej na edycję wpisu generowana jest lista tagów z tabeli "tagi", razem z checkboxami do zaznaczania. Chcę też żeby checkboxy tagów dopasowanych do filmu były już zaznaczone.
Zastosowałem kolejną pętlę while sprawdzającą dopasowania w pętli generującej tagi, ale tym sposobem zaznacza się tylko ostatni tag:

Kod z pamięci - może zawierać drobne błędy - chodzi tylko o ogólny podgląd
$tags_query = mysql_query("select * from tagi"); // wyciągnięcie wszystkich tagów while ($tagi = mysql_fetch_array($tags_query)) { $checked_query = mysql_query("select * from tagi_filmy where tagi_filmy.id_filmu=$wybrany_film[id]"); // dopasowanie tagów do wybranego filmu while ($chtags = mysql_fetch_array($checked_query)) { if ($chtags[id_tagu] == $tagi[id]) $wstaw = "checked='checked'"; // warunek do zaznaczenia else $wstaw = ''; } echo " <input type='checkbox' $wstaw />$tagi[nazwa_tagu]<br /> "; }

Prosiłbym o jakieś podpowiedzi :)



Myślałem i pisałem z półtorej godziny, ale jest. Na przykładowych danych u mnie działało xD
$tags_query = mysql_query("select * from filmy") or die(mysql_error()); while ($filmy = mysql_fetch_array($tags_query)) { echo '<fieldset><legend>'.$filmy['title'].'</legend>' ; $checked_query = mysql_query('select distinct tagi.id,tagi.tag, case when podzapytanie.id=tagi.id then 1 end as flaga from tagi,filmy,tagi_filmy,(select tagi.id from tagi,tagi_filmy where tagi_filmy.tag=tagi.id and tagi_filmy.film='.$filmy['id'].') as podzapytanie order by tagi.id,flaga desc'); $checkvar=0; while ($chtags = mysql_fetch_array($checked_query)) { if($checkvar==$chtags['id']) continue; else $checkvar++; if($chtags['flaga'] == 1) $wstaw = "checked='checked'"; // warunek do zaznaczenia else $wstaw = ''; echo '<input type="checkbox" '.$wstaw.' />'.$chtags['tag'].'<br /> '; } echo '</fieldset>'; }

na wszelki wypadek dam Ci zrzut z PMA, żebyś mógł sprawdzić na jakiej strukturze bazy to zrobiłem:
-- phpMyAdmin SQL Dump -- version 2.11.4 -- [url="http://www.phpmyadmin.net"]http://www.phpmyadmin.net[/url] -- -- Host: localhost -- Czas wygenerowania: 27 Lut 2008, 16:03 -- Wersja serwera: 5.0.51 -- Wersja PHP: 5.2.5 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -- -- Baza danych: `filmy` -- -- -------------------------------------------------------- -- -- Struktura tabeli dla `filmy` -- CREATE TABLE IF NOT EXISTS `filmy` ( `id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=4 ; -- -- Zrzut danych tabeli `filmy` -- INSERT INTO `filmy` (`id`, `title`) VALUES (1, 'Szklana pułapka'), (2, 'Moda na sukces'), (3, 'Takedown'); -- -------------------------------------------------------- -- -- Struktura tabeli dla `tagi` -- CREATE TABLE IF NOT EXISTS `tagi` ( `id` int(10) unsigned NOT NULL auto_increment, `tag` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=8 ; -- -- Zrzut danych tabeli `tagi` -- INSERT INTO `tagi` (`id`, `tag`) VALUES (1, 'bruce willis'), (2, 'akcja'), (3, 'opera mydlana'), (4, 'film'), (5, 'serial'), (6, 'hacking'), (7, 'broń'); -- -------------------------------------------------------- -- -- Struktura tabeli dla `tagi_filmy` -- CREATE TABLE IF NOT EXISTS `tagi_filmy` ( `id` int(10) unsigned NOT NULL auto_increment, `film` int(10) unsigned NOT NULL, `tag` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=9 ; -- -- Zrzut danych tabeli `tagi_filmy` -- INSERT INTO `tagi_filmy` (`id`, `film`, `tag`) VALUES (1, 1, 1), (2, 1, 2), (3, 2, 3), (4, 2, 5), (5, 1, 4), (6, 3, 4), (7, 1, 7), (8, 1, 6);

Działa :)

Wielkie dzięki!

Zamiast kilku zapytań i kilku pętli radzę użyć jednak złączeń SQL-owych (join)
Użytkownik Coldpeer edytował ten post 05 marzec 2008, 16:19


na małe obciążenie JOINy mogą być, pod dużym obciążeniem już nie ;)

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • nvm.keep.pl

  • Sitedesign by AltusUmbrae.