Systemvoraussetzung
- Linux
- Windows
- PHP 3
- PHP 4
- PHP 5
Datei(en)
checkboxen_binaer.php
Problem
Gerade bei der Speicherung von sehr vielen Checkboxen stellt sich die Frage,
wie man dieses Problem am besten umgehen kann. Stellen Sie sich ein Formular
für eine Umfrage mit z. B. 30 Checkboxen vor. Sie könnten jetzt jede einzelne
Checkbox in eine Datenbank speichern oder aber die folgende Variante nutzen.
Lösung
Checkboxen können nur zwei Zustände annehmen und sind daher entweder
aktiviert (TRUE bzw. 1) oder deaktiviert (FALSE bzw. 0). Dieses Merkmal findet
man auch in der Binärdarstellung wieder, und es kann daher zur Verwendung
für diese Technik herangezogen werden.
Binärwerte werden nur durch die beiden Zahlen 1 und 0 dargestellt. Hat
man z. B. fünf Checkboxen, von denen die erste, die zweite und die fünfte
aktiviert sind, so kann man dies auch mit folgender Schreibweise darstellen 11001.
Diese Darstellung sieht genau wie ein Binärwert aus und würde bei der
Konvertierung in eine Dezimalzahl auch ein Ergebnis liefern.
Um aber die Checkboxen in eine binäre Art zu bekommen, ist ein kleiner
Umstrukturierungsvorgang vonnöten. Binärwerte werden grundsätzlich von
rechts her aufgebaut (was auch sinnvoll ist, da man für 0000000000001 direkt
1 schreiben könnte), die Checkboxen aber von links bzw. von oben. Daher
muss man den Binärwert einfach umdrehen. Genau das erledigt das Skript von
selbst, da die Werte bereits von rechts her bestückt werden.
In unserem kleinen Beispiel wäre nun der Binärwert 10011. Dieser Binärwert
in eine Dezimalzahl konvertiert ergäbe 19. Die Zahl 19 ist der Wert, der auch
in die Datenbank gespeichert wird. Er enthält alle Informationen über die Aktivierungsart aller Checkboxen, da beim Aufbau der Checkboxen die Zahl
19 wieder in einen Binärwert konvertiert wird (10011).
Allerdings müssen im Vorfeld die Checkboxen ein wenig angepasst werden.
- Die Checkboxen erhalten alle den gleichen Namen und werden somit als Array
übermittelt. In unserem Fall heißen die Checkboxen alle checkbox_name[] (wichtig sind hier die eckigen Klammern, da nur so ein Array aufgebaut wird).
Somit kann man hier auch von einer Gruppe sprechen.
- Alle Checkboxen werden im ValueWert
durchnummeriert (1 bis max. 32).
Dies ist ein wichtiger Punkt, da nur so die richtigen Checkboxen aktiviert oder
deaktiviert werden können. Zur Erinnerung: Nicht aktivierte Checkboxen
werden nicht übermittelt. Auch wenn Sie 32 Checkboxen haben und nur 16
aktivieren, erhalten Sie beim Absenden nur ein Array mit 16 Elementen. Da
wir aber als Value-Wert
die „Position“ gespeichert haben, ist es ein Leichtes,
die nötigen Felder zu initialisieren.
- Die Spalte für die Speicherung des Wertes in der Datenbank muss auf Integer
eingestellt werden.
Zur besseren Veranschaulichung sehen wir uns folgendes Beispiel an:
Bei der Initialisierung der Variablen setzen wir den Startwert auf 0. Wird nun
das unten stehende Beispiel abgeschickt, passiert Folgendes: Bitte beachten
Sie, dass bei den Durchläufen die Checkboxen von links, die Binärwerte von
rechts gelesen werden.
Abbildung 3.9: Checkboxen
1. Durchlauf
Checkbox1 ist deaktiviert und somit 0. In diesem Fall bleibt unser Wert bei 0,
da der Startwert bereits 0 war und ein Binärwert mit der Anordnung 00 auch
als Dezimalzahl 0 ergäbe.
2. Durchlauf
Checkbox2 ist aktiviert und somit 1. Unser Binärwert wird nun von der rechten
Seite her verändert. Die zweite Stelle des Binärwerts wird auf 1 gesetzt. Der
Wert ist nun 10.
3. Durchlauf
Checkbox3 ist aktiviert und somit 1. Unser Binärwert wird nun von der rechten
Seite her verändert. Die dritte Stelle des Binärwerts wird auf 1 gesetzt. Der
Wert ist nun 110.
4. Durchlauf
Checkbox4 ist deaktiviert und somit 0. In diesem Fall bleibt unser Wert bei
110.
5. Durchlauf
Checkbox5 ist deaktiviert und somit 0. In diesem Fall bleibt unser Wert bei
110.
6. Durchlauf
Checkbox6 ist aktiviert und somit 1. Unser Binärwert wird nun von der rechten
Seite her verändert. Die sechste Stelle des Binärwerts wird auf 1 gesetzt. Somit
erhalten nun auch die vierte und fünfte Stelle ihren Wert, jeweils die 0. Der
Wert ist nun 100110.
Den Wert 100110 lassen wir uns mit der Funktion bindec() als Dezimalzahl
ausgeben und erhalten als Ergebnis die Zahl 38. Diese Zahl speichern wir in
der Tabelle ab. Das war es schon! Wir haben nun eine schlanke Lösung für
ein großes Problem. In Zukunft wird das Skript nur noch mit der einzelnen
dezimalen Zahl arbeiten, um die Checkboxen zu bestücken.
Achtung!
Einen kleinen Haken gibt es aber. Wir können mit dieser Methode nur maximal
32 Checkboxen verwalten, da wir bei dieser Zahl an die Grenze eines IntegerWerts
gehen. Gruppen können aber in rauen Mengen erstellt werden.
Wir werden uns jetzt genauer den Programmcode für unsere Lösung anschauen.
Er ist einfacher, als Sie denken.
function setBit(&$bitField,$n)
@param integer $bitField
@param integer $n
@return bool
Die Funktion setBit() erwartet als Parameter zum einen den binären Wert
für unsere Checkboxen und zum anderen die aktivierte Checkbox. Im ersten
Schritt müssen wir überprüfen (8), ob der Wert für die aktivierte Checkbox
zwischen 0-32
liegt. Ist der Wert außerhalb von 0-32,
beenden (8) wir die
Funktion an dieser Stelle.
Sollte der Wert zwischen 0-32
liegen, können wir den Binärwert für unsere aktivierte
Checkbox setzen (16). Wenn wir also annehmen, dass wir 15 Checkboxen
haben, ergibt sich ein Wert von
100000000000000
Wenn wir jetzt die 15. Checkbox aktivieren wollen, müssen wir den Wert
von rechts her mit einer 1 (Eins) auffüllen (16). Der Wert „100000000000000“
entspricht dann der Zahl 16384. Bei dem PineZeichen
(|) vor dem Leerzeichen
handelt es sich nicht um das logische ODER, sondern um das BIT-ODER.
003:
004: 005: 006: 007: 008: 009: 010: 011: 012: 013: 014: 015: 016: 017: 018: 019: | function setBit(&$bitField,$n) {
// Ueberprueft, ob der Wert zwischen 0-33 liegt // $n ist hier der Wert der aktivierten Checkbox, z.B. 15 // Somit waere hier die 15. Checkbox aktiviert if(($n < 0) or ($n > 32)) return false; // Bit Shifting // Hier wird nun der Binaerwert fuer die aktuelle Checkbox gesetzt. // In unserem Beispiel wird hier nun die 15. Stelle von rechts auf 1 gesetzt // 100000000000000 <-- Dieses entspricht der Zahl 16384 // | ist nicht das logische ODER sondern das BIT-oder $bitField |= (0x01 << ($n-1)); return true; } |
Beispiel 3.21: checkboxen_binaer.php
function clearBit(&$bitField,$n)
@param integer $bitField
@param integer $n
@return bool
Die Funktion clearBit() erwartet als Parameter den binären Wert für unsere
Checkboxen und die deaktivierte Checkbox. Wir müssen hier lediglich das Bit
wieder auf 0 (Null) setzen (25). Bei dem kaufmännischen UND (&) handelt es
sich nicht um das logische UND, sondern um das BIT-UND.
021:
022: 023: 024: 025: 026: 027: 028:
| function clearBit(&$bitField,$n) {
// Loescht ein Bit oder ein Bitfeld // & ist nicht das logische UND sondern das BIT-and $bitField &= ~(0x01 << ($n-1)); return true; } |
Beispiel 3.22: checkboxen_binaer.php
function function isBit(&$bitField,$n)
@param integer $bitField
@param integer $n
@return bool
Die Funktion isBit() erwartet als Parameter den binären Wert für unsere
Checkboxen und die zu prüfende Checkbox. Wir überprüfen hier lediglich, ob
die x-te
Stelle eine 1 (Eins) ist oder nicht (32).
030: 031: 032: 033: 034: | function isBit($bitField,$n) {
return (($bitField & (0x01 << ($n-1)))); }
|
Beispiel 3.23: checkboxen_binaer.php
Der restliche Programmcode besteht hauptsächlich aus Überprüfungen und
Darstellungen der Checkboxen. Sie sollten aber unbedingt die Variable für die
Checkboxenmenge (40) setzen, die angibt, wie viele Checkboxen Sie darstellen
wollen.
Wenn das Formular gesendet wurde, wird im ersten Schritt überprüft (39) wie
viele Checkboxen übertragen wurden. Ist der Wert kleiner als 1 (Eins) oder
größer als 32, wird der Standardwert (hier 32) gesetzt. War alles in Ordnung,
also der Wert zwischen 1-32,
wird die Menge gespeichert (42).
Falls das Formular nicht gesendet wurde (50), also sich im Grundzustand
befindet, gibt es zwei Möglichkeiten. Entweder starten Sie das Formular mit
leeren Checkboxen (53), indem Sie eine 0 (Null) in die Variable speichern, oder
aber Sie machen eine Datenbankabfrage von der Spalte mit dem Dezimalwert
für die Checkboxen. Dieser Wert müsste dann in die Variable (53) gespeichert
werden.
Je nachdem, ob nun ein Wert vorliegt (70), wird der Wert in die jeweilige
Variable (57 oder 59) gespeichert. Wir durchlaufen jetzt die Checkboxenmenge
(40) und überprüfen (70) bei jedem Durchlauf, ob die x-te
Stelle (also jeweils
das Array-Index)
in unserem Wert eine 1 (Eins) ist.
Falls ja, so speichern wir in unserem Array für die Checkboxen im Formular
unter dem jeweiligen ArrayIndex
den String „checked“. Somit wird nachher
jede einzelne Checkbox de- oder
aktiviert. 037:
038: 039: 040: 041: 042: 043: 044: 045: 046: 047: 048: 049: 050:
051: 052: 053: 054: 055: 056: 057: 058: 059: 060: 061: 062: 063: 064: 065: 066: 067: 068: 069: 070: 071: 072: 073: 074: 075: 076: | * Die Menge der Checkboxen sollten hier angegeben werden
*/ if( $_POST["checkboxen"] < 1 || $_POST["checkboxen"] > 32) $checkboxen = 32; else $checkboxen = $_POST["checkboxen"];
/* * Hier sollte der Wert aus einer Datenbank geholt werden * Dies sollte aber nur beim ersten Aufruf geschehen */ if( !isset($_POST["checkbox_name"]) && !is_array($_POST["checkbox_name"])
&& !isset($_POST["CheckboxenBinaer"]) ){
// Select der Datenbankabfrage hier einfuegen und den Wert // in $wertAbfrage speichern $wertAbfrage = 0; // Ueberpruefung ob ein Wert vorhanden ist if( !empty($wertAbfrage) ) $bitmask = $wertAbfrage; else $bitmask = 0x0; // Durchlaeuft schrittweise alle Elemente von $bitmask. foreach(range(1,$checkboxen) as $position){ // Ueberprueft, ob die x-te Stelle eine 1 ist und speichert bei Erfolg // ein "checked" in das Arrayelement fuer die x-te Position. // Beispiel: $position ist 6. Nun wird die 6.Stelle von rechts innerhalb // der Variablen $bitmask auf eine 1 hin ueberprueft. Steht an dieser Stelle // eine 1, so wird in $formCheck[6] ein "checked" gespeichert. // Somit wird die sechste Checkbox aktiviert. if(isBit($bitmask,$position)) { $formCheck[$position] = " checked"; } } }
|
Beispiel 3.24: checkboxen_binaer.php
Falls das Formular gesendet wurde, können wir in den else-Zweig
(77) springen
und unseren neuen Wert für die Checkboxen speichern. Wir überprüfen zuerst,
ob überhaupt eine Checkbox aktiviert wurde (83), um im nächsten Schritt die
aktivierten Checkboxen in der Funktion setBit() (88) in unsere Variable zu
speichern.
Wie bereits zuvor setzen wir die Markierungen, falls der aktuelle Array-Index
eine 1 (Eins) enthält, für unsere Checkboxen (92). Wir speichern zum Schluss
den Wert der BIT-Abfrage
in unsere Variable (100). Diesen Wert können Sie
jetzt in die Datenbank speichern.
077: 078: 079: 080: 081: 082: 083: 084: 085: 086: 087: 088: 089: 090: 091: 092: 093: 094: 095: 096: 097: 098: 099: 100: 101: 102:
| else{
// Das Formular wurde versendet und die Checkboxen muessen // nun konvertiert werden. // Wurde ueberhaupt eine Checkbox aktiviert? If( isset($_POST["checkbox_name"]) ){ foreach($_POST["checkbox_name"] as $position){ // Setzen der einzelnen Checkboxen in der Binaerstruktur setBit($bitmask,$position); // Ist die Checkbox aktiviert? if(isBit($bitmask,$position)) { $formCheck[$position] = " checked"; } } } // Hier kann nun auch der Wert wieder in die Datenbank geschrieben werden $neuerWert = $bitmask; }
|
Beispiel 3.25: checkboxen_binaer.php
Das eigentliche Formular dagegen ist unspektakulär. Zum Testen haben wir
zuerst eine Ausgabe unseres Wertes für die Datenbank (108) und zum anderen
den gleichen Wert als Binärwert (109). Sie können das Formular auf Ihrem
Server ausprobieren und sich die jeweiligen Werte ausgeben lassen. Anhand der
Werte werden Sie sehr schnell ein Gefühl für die hier erklärte Vorgehensweise
bekommen.
Nun müssen wir lediglich noch die Checkboxen aufbauen. Wir durchlaufen
daher eine FOR-Schleife
(110) mit der Menge der Checkboxen. Da wir bereits
den Wert für die De- oder
Aktivierung unserer Checkboxen in einem Array
gespeichert haben, müssen wir diesen nur noch ausgeben (113).
106: 107: 108: 109: 110:
111: 112: 113:
114: 115: 116: 117: 118:
119: 120:
| <form name="form" method="post" action="<?PHP echo $PHP_SELF; ?>">
<?PHP echo 'Der Dezimalwert für diese Anordnung ist: <b>' . $bitmask . '</b><br>'; echo 'Der Binärwert für diese Anordnung ist: <b>' .
decbin($bitmask) . '</b><br>'; for($x=1;$x<=$checkboxen;$x++){ ?>
<input type="checkbox" name="checkbox_name[]"
value="<?PHP echo $x; ?>" <?PHP echo $formCheck[$x]; ?>>
<?PHP } ?> <br>Menge der Checkboxen <input type="text" name="checkboxen"
value="<?PHP echo $_POST["checkboxen"]; ?>">
<br><input type="submit" name="CheckboxenBinaer" value="Send"><br> </form>
|
Beispiel 3.26: checkboxen_binaer.php
Wie Sie sehen, haben wir hier eine Lösung für das Checkboxenproblem geliefert.
Sollten Sie mehr als 32 Checkboxen benötigen, erstellen Sie einfach eine neue
Gruppe. In dieser Gruppe haben Sie dann wieder 32 mögliche Zustände zur
Verfügung.
Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!
Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.
|