Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php][mysql] Jak najlepiej zapisać dane z wielu checkboxów?
Forum PHP.pl > Forum > PHP
wdev
Witam,

Robię w php i mysql bazę danych do zleceń produkcji. Elementem formularza jest pole 22 checkboxów (opcje dodatkowe), które muszę później zapisać i odczytać z bazy danych. Opcje te mogą się zmieniać, dlatego dobrze by było, gdyby dało się je łatwo edytować.

Stworzyłem tabelę `opcje` (id, nazwa) i do formularza pobieram z niej wszystkie. Przy zapisywaniu do tabeli `zlecenia` przez funkcję implode() wrzucam je jako jeden łańcuch do komórki opcje_dodatkowe. Później, zależnie od potrzeb muszę zrobić explode() i porównać z odpowiednimi id w tabeli `opcje`. Boję się jednak, że takie rozwiązanie okaże się na dłuższą metę bardzo zasobożerne - już teraz łańcuch numerków z 22 checkboxów może mieć ponad 50 znaków. Czy ktoś ma pomysł jak to lepiej ugryźć?
neverever
możesz też sklecić stringa o długości 22znaki dla tych 22 checkboxów - dla kazdego checka przyporządkowujesz stan 0 - odznaczony, 1 - zaznaczony

...i tak masz dajmy: 0010011101... dry.gif

-zawsze to 22 znaki a nie 50 czy więcej
-operować na tym też jest łatwo zarówno na poziomie zapytania sql jak i w skrypcie
Crozin
Robisz dodatkową tabelę łączącą zlecenie z opcjami:
zlecenie_id
opcja_id

Dodanie 22 opcji do jednego zlecenia to 22 rekordy w takiej tabeli.


A nie jakieś łączenie w tekst, co potem o kant d..y rozbić można.

PS. Podstawowa relacja n-n...
Pilsener
Dokładnie tak jak poprzednik napisał:

Cytat
przez funkcję implode() wrzucam je jako jeden łańcuch do komórki opcje_dodatkowe
- robisz tabelę gdzie wrzucasz id_zlecenia i id_opcji - jak inaczej chcesz to łatwo edytować?

A same opcje w HTML zapisuj tak:
  1. <input type="checkbox" name="opcje[]" value="123" />
  2. <input type="checkbox" name="opcje[]" value="987" />
- i w POST masz od razu tablicę "opcje" która zwiera identyfikatory (czyli value) tych czekboksów, które zostały zaznaczone, co czyni sprawę banalnym jeśli użyjemy w mysql IN, np.
  1. DELETE FROM opcje WHERE id_opcji IN(23,45,67,789)
- gdzie id opcji to implode/join tablicy opcje przecinkiem
wdev
Ech... No wielkie dzięki smile.gif Dawno już takich rzeczy nie robiłem i sporo się pozapominało.

Jeszcze raz, duże dzięki, bardzo pomogliście.
Ges
Ja bym proponował bardziej wydajne rozwiązanie do tego stworzone, użycie pola SET w MYSQL:

http://dev.mysql.com/tech-resources/articl...t-datatype.html

ZA:
+ można wyszukiwać po tym polu bezpośrednio na bazie danych wszystkich którzy wybrali konkretną opcję
+ można też wyszukiwać wszystkich z zewstawem konkretnych opcji
+ bedziesz mógł robić JOINy nawet po tych opcjach
+ możesz podmieniać poszczególne flagu bardzo szybko (dodawać / usuwać konkretne opcje) bez konieczności przebudowywania całego stringu i wszystkich operacji po drodze

inaczej jeśli będziesz chciał zebrać chociażby statystyki lub ilu ludzi wybrało konkretną opcje, bedziesz musiał pobrać całą bazę danych exclamation.gif Wszystkich użytkowników (sic !), explodować za każdym razie wszystkie opcje i jeszcze potem robić ogromny zestaw ifów po explodzie sprawdzający czy (pytanie1 && pytanie2 && pytanie 3) - meeeeeega słaba opcja...

PRZECIW:
- ograniczasz się do 64 flag które możesz zastosować

Oczywiście jeśli tylko pole to używasz do zapisu i odczytu stanu tego co ma użytkownik w opcjach, to opcja zapropowana przez poprzedników też będzie działać.
neverever
Ges, no też ciekawe rozwiązanie.

Szczerze, to wszystko zależy od konkretnej sytuacji. Relacja 1:1 nie zawsze jest najlepsza.
No i też zawsze to nowa tabela z minimum 2 kolumnami id i opcja, no i tez tyle tych rekordów ile w najlepszym wypadku zaznaczonych tylko checków, w najgorszym tyle ile wszystkich checków ...jeszcze pomnożyć przez ilość userów i mamy już dosyć pokaźne wielkości.

Podane przeze mnie rozwiązanie nie jest idealne, ale też nie jest jakieś skomplikowane.

Opiera się na jednej kolumnie o długości n znaków, każdy odpowiada kolejnemu checkowi i przyjmuje wartość 1 lub 0 - coś na wzór maski bitowej.
Nie trzeba nic explodować, łatwo też tym operować na poziomie zapytania stosując wzorzec lub odwołując się do konkretnego znaku lub znaków (stanu checkboxa) za pomocą SUBSTRING.

Tak czy owak, akurat w kilku sytuacjach wygodniej mi było przeznaczyć na usera 1 pole o długości 100bajtów,
niż w nowej tabeli 100 rekordów po minimum 5 bajtów każdy (4 na id usera i 1 id checkboxa)

-wprawdzie oszczędniej było by operować na pojedyńczych bitach, nie zaś na całych bajtach.

W sumie metoda trochę zbliżona do tej jaką zapodał Ges. dry.gif






To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.