SELECT und Namensliste übersichtlich halten (incl. mysql)
Bernhard W.
- php
Hi, ich möchte mit einem SELECT-Objekt eine Namensliste mit Unterteilung der Anfangsbuchstaben der Vornamen erstellen. Also so in etwa:<br>
-------<br>
A<br>
ein Name mit A<br>
anderer Name mit A<br>
B<br>
ein Namen mit B<br>
anderer Name mit B<br>
-------<br>
Bisher habe ich den folgenden Code geschaft (wahrscheinlich etwas unelegant; bin nur Programmer-Praktikant *g*):<br>
<div id="adrfeld" ><br>
<? $abfr = "SELECT benutzer
.vname
, benutzer
.name
, benutzer
.strasse
, orte
.ort
<br>
FROM benutzer
LEFT JOIN orte
ON benutzer
.ort-nr
= orte
.id
<br>
ORDER BY benutzer
.vname
ASC";<br>
$res = mysql_query($abfr);?><br>
<form style="float:right"><br>
<select name="Auswahl" size="20" style="border:0px; width:155px;" <br>overflow:hidden;"onchange="showAddress(this.form.Auswahl.options[this.form.Auswahl.selectedIndex].value)"><br>
<? while($ausg = mysql_fetch_object($res)) { $ind=$ausg->vname; <br>$index=$ind[0]; $initi=$ausg->name; ?><br>
<optgroup label="<? echo $index;?> "><br>
<option value="<? echo $ausg->strasse;?>, <? echo $ausg->ort;?>"><br>
<? echo $ausg->vname;?> <? echo $initi[0];?>.</option> <br>
</optgroup> <? } //while-ende ?><br>
</select><br>
<? mysql_free_result($res);?><br>
</form><br>
<p style="font-size:50%;i;text-align:right">für Anzeige Name auswählen</p><br>
</div>
Über die While-Schleife verarbeitet er mir zwar alles richtig, aber <br>halt bei jedem eintrag in die DB macht er auch eine neue <br>optgroup-Initiale.<br>
Wie könnte ich das ausbessern/verschachteln??<br>
Hoffe ihr könnt mir weiter helfen.<br>
Braucht man jetzt diese "<br>" doch nicht?
Des Absende-Formular hat was von "unübersichtlicher Darstellung"
gemekert, da hab ich die <br>-s hinzugefügt.
Also falls se unnötig waren einfach nicht beachten.
Gruss
Hallo Bernhard,
A
ein Name mit A
anderer Name mit A
B
ein Namen mit B
anderer Name mit B
<? $abfr = "SELECT
benutzer
.vname
,benutzer
.name
,benutzer
.strasse
,orte
.ort
<br>
FROMbenutzer
LEFT JOINorte
ONbenutzer
.ort-nr
=orte
.id
<br>
ORDER BYbenutzer
.vname
ASC";<br>
meine erste Anmerkung:
Verlasse Dich lieber nicht auf short_open_tag=on verlassen und statt dessen eine der beiden beschriebenen _immer_ funktionierenden Methoden verwenden, um PHP-Bereiche zu kennzeichnen.
zweitens:
Du benutzt nur die Spalten
vname, name und strasse
Deiner Abfrage. Deswegen ist es eine gute Idee, auch nur diese Felder abzufragen:
SELECT
vname, -- vollqualifizierte Spaltennamen sind nur erforderlich
name, -- wenn diese innerhalb der Tabellen einer Abfrage
strasse -- nicht eindeutig sind
FROM benutzer b -- Aliasnamen helfen Schreibarbeit zu sparen
LEFT JOIN orte ON b.`ort-nr` = orte.id -- Spalten mit Sonderzeichen
-- sind meist keine gute Idee
-- Das Minuszeichen hat eine
-- besondere Bedeutung :-)
ORDER BY vname -- Aufsteigend ist die Standardsortierreihenfolge
-- Das Semikolon am Ende der SQL-Anweisung solltest Du
-- weglassen.
$res = mysql_query($abfr);?>
<form style="float:right">
Ständiger Wechsel zwischen PHP- und HTML-Bereichen ist keine gute Idee.
Speichere lieber vorher die Daten, die Deine Datenbankabfrage zurückliefert, in einem Array zwischen und schreibe dann z.B. mit echo das HTML.
<br>$index=$ind[0]; $initi=$ausg->name; ?><br>
<optgroup label="<? echo $index;?> "><br>
Speichere den zuletzt ermittelten Anfangsbuchstaben in einer Variable.
Überprüfe bei jedem Durchlauf, ob sich dieser geändert hat.
Schreibe optgroup nur dann, wenn eine Änderung erfolgt.
<p style="font-size:50%;i;text-align:right">für Anzeige Name auswählen</p><br>
Inline-CSS macht den Code nicht lesbarer und erst recht nicht wartbarer. Nutze geeignete Selektoren. Die Lektüre von SELFHTML kann Dir dabei helfen. Eine geeignete Wahl der Zeichenkodierung macht übrigens die Verwendung von ü und Konsorten überflüssig.
Und nein, Du musst hier in der Textarea eine Zeile _nicht_ mit <br> abschließen. Es gibt übrigens eine Vorschau ;-)
Freundliche Grüße
Vinzenz
Hallo Vinzenz
Ständiger Wechsel zwischen PHP- und HTML-Bereichen ist keine gute Idee.
Hab erst angefangen mit php und mysql zu arbeiten. Des ständige Wechseln zw. php und html macht die Quell-Datei auch recht unübersichtlich.
Ich bemühe mich aber weiter.
Speichere lieber vorher die Daten, die Deine Datenbankabfrage zurückliefert,
in einem Array zwischen und schreibe dann z.B. mit echo das HTML.
Ist das nicht etwas unpraktisch? Dadurch würd ich die Festplatte doch wegen einer kleinen Abfrage ziemlich belasten.
Ists on-fly ned schneller und effizienter?
Speichere den zuletzt ermittelten Anfangsbuchstaben in einer Variable.
Überprüfe bei jedem Durchlauf, ob sich dieser geändert hat.
Schreibe optgroup nur dann, wenn eine Änderung erfolgt.
Genau an dieser Stelle habe ich ja mein Problem, ich weis nämlich nicht wie ich die Überprüfung hinkriege!!
Wie sind meine Abfrage-Ausgaben eigentlich zwischengespeichert? Als Array oder Objekt?
Was ist da der Unterschied? (Hab das fetch_object übers google'n gefunden und's läuft damit,
wenn ich auf Array umstell beim Ausführen hauts nicht mehr hin.)
Hallo Bernhard,
Ist das nicht etwas unpraktisch? Dadurch würd ich die Festplatte doch wegen einer kleinen Abfrage ziemlich belasten.
Festplattenzugriffe sollte es dabei keine geben.
Ists on-fly ned schneller und effizienter?
Wahrscheinlich weder noch. Effizienter Code ist übrigens auch wartbarer Code. Dein Code ist nicht wartbar.
Wie sind meine Abfrage-Ausgaben eigentlich zwischengespeichert? Als Array oder Objekt?
Lies bitte den entsprechenden Handbuchabschnitt.
Speichere den zuletzt ermittelten Anfangsbuchstaben in einer Variable.
Überprüfe bei jedem Durchlauf, ob sich dieser geändert hat.
Schreibe optgroup nur dann, wenn eine Änderung erfolgt.Genau an dieser Stelle habe ich ja mein Problem, ich weis nämlich nicht wie ich die Überprüfung hinkriege!!
Folgender Algorithmus könnte dies in etwa bewirken (sowas wie Pseudocode):
Lies Deine Daten in ein zweidimensionales Array (Du könntest Dir dies als Tabelle vorstellen ein).
Setze Letzter_Anfangsbuchstabe auf Leerstring
Solange es noch Zeilen in Deinem Array gibt
Ermittle den Anfangsbuchstaben des Namens
Wenn dieser Anfangsbuchstabe ungleich Letzter_Anfangsbuchstabe ist
Setze Letzter_Anfangsbuchstabe auf aktuellen Anfangsbuchstaben
Schreibe Optgroup mit diesem Anfangsbuchstaben
Ende Wenn
Schreibe den Namenseintrag
Hole die nächste Zeile
Ende Solange
Ich empfehle Dir ganz dringend, das PHP-Handbuch, das MySQL-Handbuch Deiner MySQL-Version und die PHP-FAQ in Deine Lesezeichen mitaufzunehmen. Ich wüßte nicht mehr, wie ich ohne diese auskäme.
<anmerkung type="Godot">
Bei Fragen zu MySQL ist es immer eine gute Idee, die genaue Version anzugeben, da sich der Leistungsumfang von MySQL sehr stark versionsbedingt unterscheidet. *bg*
</anmerkung>
Ach ja, SELECT (in Großbuchstaben) im Thema ist natürlich ein weiterer Faktor für die Bewertung als unsauberes Posting :-)
Freundliche Grüße
Vinzenz
Ich hab für die Initialen ja schon die Variable $index, bräuchte also nur noch die Überprüfungsanweisung entwicklen und diese in der richtigen Form in die While-Schleife einbinden, oder so ähnlich :-)
<p style="font-size:50%;text-align:right">für Anzeige Name auswählen</p><br>
Dieses Absatz-Element ist übrigens nur als Fußnoten-Hinweistext und steht nicht in der Schleife.
echo $begrüßung;
Vinzenz hat ja schon eine Menge gesagt, ich gebe auch noch meinen Senf dazu, zu einem nicht unwichtigen Thema.
$res = mysql_query($abfr);
while($ausg = mysql_fetch_object($res))
Ein gern gemachter Anfängerfehler ist, nur den Gutfall zu betrachten. Doch die Welt ist schlecht, die des Programmierers ganz besonders :-) Man will auf eine Datenbank zugreifen, aber das dumme Ding macht grad eine mit der Gewerkschaft nicht abgestimmte Pause. mysql_query() ist also nicht erfolgreich gewesen. Was macht es in so einem Fall? Das Handbuch klärt auf. Statt des erwarteten Ressourcen-Wertes liefert es false zurück. Nun soll mysql_fetch_object() an die Reihe kommen und das ist genau wie seine Geschwister mysql_fetch_array() usw. etepetete. Es mag nicht mit booleschen Werten gefüttert werden. Nur Ressourcen-Werte will es haben. Wenn es keinen solchen bekommt, beklagt es sich bitterlich und versaut das schöne HTML-Layout mit einer unformatierten Warnung.
Was also tun? Fehlermeldungen auszuschalten oder zu unterdrücken ist die denkbar schlechteste Alternative. Gleich danach kommt das Sterbenlassen des Scripts, wenn ein Fehler auftrat. Das oft verwendete
$res = mysql_query($sql) or die('Fehler aufgetreten: ' . mysql_error());
ist zwar schnell hingeschrieben, aber sehr benutzerunfreundlich und eine wegen des Abbruchs unvollständig angezeigte Seite sieht auch nicht gerade professionell aus.
Ein besserer Weg ist, sich das aus dem Tutorial <del>gekla</del>kopierte Beispiel genau anzusehen, und zu den verwendeten Funktionen die Beschreibung im Handbuch nachschlagen. Dort schaue man, was für Parameter die Funktion erwartet und welche Werte sie zurückliefert - sowohl im Gutfall als auch im Fehlerfall. Nun sollte man sich Gedanken machen, wie die Anwendung im Falle eines Fehlers reagieren soll. Diese Frage sollte man sich aus zwei Perspektiven stellen: Anwender und Systembetreiber. Während der Entwicklung ist es ohne Frage sinnvoll, sich den genauen Wortlaut des Fehlers anzuzeigen, doch wenn die Anwendung für die vorgesehenen Benutzer freigegeben wird sind solche Meldungstexte ob der gezeigten Information entweder unverständlich (DAU) oder gefährlich (böser Bube). Eine allgemein gültige, beste Verfahrensweise gibt es nicht. Vielmehr muss der Betreiber des Systems festlegen, was er gern in einem solchen Fall haben möchte. Drei Vorschläge wären:
Auf jeden Fall aber sollte der Programmablauf so gestaltet werden, dass nicht aufgrund des einen Fehlers viele Folgefehler hinterher kommen.
echo "$verabschiedung $name";