Array Problem - explode oder strtok oder wie???
PHP NEWBE
- php
Hi,
habe ein Problem mit dem Ausgeben einer Datenbankabfrage (MySql 4 und PHP 5).
Ich habe leider keinen Einfluss auf die Struktur der Datenbank, sonst hätte ich das anders gelöst...
select id, titel, comp, int as name, int as inter from table order by inter
jetzt habe ich das Problem, daß im Feld int mehrere Namen stehen getrennt durch Komma (also z.B. Hans Meier, Peter Springinsfeld etc.)
Die Ausgabe soll werden:
Hans Meier
-id - titel - comp - inter
-id - titel - comp - inter
Peter Springinsfeld
-id - titel - comp - inter
etc.
(Hoffe das ist verständlich ausgedrückt....)
So und nun habe ich zwei Probleme:
wie bekomme ich die Namen einzeln hin und habe trotzdem alle Informationen die dem jeweiligen Datensatz zu geordnet sind
Wie sortiere ich das vernünftig? Am besten wäre ja eine Sortierung nach Nachnamen aber ich denke mal das ist nicht machbar, irgendwelche guten Vorschläge?
Danke und Grüße,
Hans
Hi,
jetzt habe ich das Problem, daß im Feld int mehrere Namen stehen getrennt durch Komma (also z.B. Hans Meier, Peter Springinsfeld etc.)
So und nun habe ich zwei Probleme:
- wie bekomme ich die Namen einzeln hin und habe trotzdem alle Informationen die dem jeweiligen Datensatz zu geordnet sind
Welche Zuordnung besteht denn ueberhaupt?
Wenn im Feld int mehrere Namen stehen - wie soll denn dann ein Datensatz ueberhaupt eindeutig einem Namen zugeordnet sein? Oder existiert gar keine Eindeutigkeit?
- Wie sortiere ich das vernünftig? Am besten wäre ja eine Sortierung nach Nachnamen aber ich denke mal das ist nicht machbar, irgendwelche guten Vorschläge?
Wenn du immer vom Prinzip "Vorname Nachname" ausgehst, kannst du natuerlich auch das leicht noch mal splitten, und zur Sortierung nutzen (die wuerde ich dann scriptseitig machen, Zeichenkettenoperationen auf der Datenbank, deren Resultate dann auch noch das Ergebnis beeinflussen sollen [Sortierung], sind zu teuer). Allerdings sollte dabei ueberlegt werden, wie Sonderfaelle behandelt werden bzw. ggf. abgefangen werden koennen (mehrere Vornamen, aus mehreren Woertern bestehender Nachname).
MfG ChrisB
Welche Zuordnung besteht denn ueberhaupt?
Wenn im Feld int mehrere Namen stehen - wie soll denn dann ein Datensatz ueberhaupt eindeutig einem Namen zugeordnet sein? Oder existiert gar keine Eindeutigkeit?
Das ist genau das Problem -> der Datensatz soll dann eben zwei Namen (oder drei, vier jenachdem wieviele da drin sind) zugeordent werden und jeweils unter dem Namen ausgegeben werden.
Also
Name 1
Datensatz 1
Datensatz 2
Name2
Datensatz 2
Datensatz 7
Name3
Datensatz 1
Datensatz 2
Datensatz 3
etc....
Wenn du immer vom Prinzip "Vorname Nachname" ausgehst, kannst du natuerlich auch das leicht noch mal splitten, und zur Sortierung nutzen (die wuerde ich dann scriptseitig machen, Zeichenkettenoperationen auf der Datenbank, deren Resultate dann auch noch das Ergebnis beeinflussen sollen [Sortierung], sind zu teuer). Allerdings sollte dabei ueberlegt werden, wie Sonderfaelle behandelt werden bzw. ggf. abgefangen werden koennen (mehrere Vornamen, aus mehreren Woertern bestehender Nachname).
Da hänge ich auch gerade ganz schön und komme nicht weiter....
Wenn ich nur die Datenbank ändern dürfte.... m
Grüße,
Hi,
Das ist genau das Problem -> der Datensatz soll dann eben zwei Namen (oder drei, vier jenachdem wieviele da drin sind) zugeordent werden und jeweils unter dem Namen ausgegeben werden.
Dann sollte man das am besten in dem Zeitpunkt zuordnen, an dem man die Daten im Script in Empfang nimmt.
Das Abfrageergebnis wirst du ja vermutlich jetzt schon in einer Schleife abarbeiten.
Ich wuerde in dieser
a) die Datensaetze in einem Array ablegen, mit der Datensatz-ID als Schluessel, und
b) den Inhalt des Namens-Feldes in einzelne Namen aufsplitten, und diese ebenfalls in einem Array ablegen - Name als Key, und dann die ID des Datensatzes darunter in einem weiteren Array. Das kann, wenn $array einmal als Array initialisiert wurde, ganz simpel ueber die Syntax $array[$name][] = $id geschehen.
Zur Ausgabe durchlaeufst du dann dieses zweite, ggf. vorher noch sortierte, Array, wiederum in einer Schleife - und holst dir dabei ueber die IDs wieder die zugehoerigen Datensaetze, die im ersten Array abgelegt wurden.
MfG ChrisB
Hi,
heißt das jetzt, dass die Namen auch immer wieder vorkommen können?
Denn dann heißts, alles einlesen und mühsam wieder auseinanderschustern...
Sehr viel einfacher wirds, wenn ein Name aus Datensatz 1 nie mehr wieder in einem späteren Datensatz vorkommen wird.
Grüße, Franz
echo $begrüßung;
der Datensatz soll dann eben zwei Namen (oder drei, vier jenachdem wieviele da drin sind) zugeordent werden und jeweils unter dem Namen ausgegeben werden.
Eine Zuordnung von einem Schlüsselwert zu beliebien Daten kann man in PHP mit einem Array abbilden. Die Namen sind die Keys, die Werte sind ein oder mehrere Datensätze, also ein Array aus Datensätzen.
Beim Auslesen des Abfrageergebnisses, trennst du die Namen auf und für jeden Namen schaust du nach, ob es bereits einen Key im Array gibt und hängst an das vorhandene Array zu diesem Key den Datensatz an. Wenn der Name noch nicht vorkommt, fügst du in das Hauptarray ein Array mit dem Datensatz unter dem Namen hinzu.
Anschließend kannst du zwecks Ausgabe durch das äußere Array laufen und durch die inneren ebenso.
echo "$verabschiedung $name";
Erstmal danke an alle für die Tipps! Bin mir aber noch nicht sicher, ob ich die wirklich verstanden habe....
$ausgabe=array();
$query="select id, titel, inter as name, inter as inter from table order by inter";
$erg=mysql_query($query);
if(!erg)
die("Abfrage klappt nicht");
else
{
while($aus=mysql_fetch_array($erg))
{
$name=explode(",",$aus["name"]);
$zwischen=array('id'=>$aus["id"],'titel'=>$aus["titel"], 'inter'=>$aus["inter"]);
foreach($name as $inhalt=>$wert)
{
$abc=array('Name'=>$wert);
$ausgabe[]=array_merge($abc,$zwischen);
}
}
}
print_r($ausgabe);
So, nun habe ich für jeden Namen die Datensätze, aber so wie Ihr das vorgeschlagen habt (schauen ob Name schon vergeben ist und dann den Datensatz dort zuordnen: keine Ahnung wie ich das machen soll)
Wie kontrolliere ich ob der Name schon mal vorgekommen ist?
Wie sortiere ich das Array nach Namen?
Und vor allem so wie ich das jetzt geschrieben habe dauert die Abfrage ewig und drei Tage....
Sorry, aber ich raff es nicht!
echo $begrüßung;
Wie kontrolliere ich ob der Name schon mal vorgekommen ist?
So, meinte ich, soll es am Ende pro Namen aussehen.
$ausgabe['name'] = array(array(ein datensatz), array(noch ein datensatz), ...);
Du testest dann mit isset($ausgabe[$wert]) auf Vorhandensein. ($wert steht ja in deinem Fall für einen Namen. Aussagekräftigere Bezeichner erleichtern das Quellcode-Lesen.)
Wie sortiere ich das Array nach Namen?
Mit den üblichen Array-Sortierfunktionen. Siehe Array-Funktionen.
Und vor allem so wie ich das jetzt geschrieben habe dauert die Abfrage ewig und drei Tage....
Dann analysiere, welcher Teil die Zeit verbraucht. Beispielsweise mit microtime().
echo "$verabschiedung $name";
Hi,
danke für die ausführliche Hilfestellung, und sorry, dass ich schon wieder nerve.
Habe das jetzt so geschrieben und das scheint zu funktionieren:
while($aus=mysql_fetch_array($erg))
{
$leute=explode(",",$aus["name"]);
$zwischen=array('id'=>$aus["id"],'titel'=>$aus["titel"], 'inter'=>$aus["inter"]);
foreach($leute as $inhalt=>$name)
{
$name=trim("$name");
if(isset($ausgabe[$name]))
{
array_push($ausgabe[$name],$zwischen);
}
else
{
$ausgabe[$name]=array();
array_push($ausgabe[$name],$zwischen);
}
}
}
Hoffe mir sind hier keine Tipfehler unterlaufen... Zeitproblem ist anscheinend auch gelöst lag wohl hauptsächlich an print_r....
Mit dem Sortieren habe ich allerdings noch Probleme. Gehe mal davon aus, dass array_multisort(); zu verwenden ist. Nun möchte ich nach $ausgabe[$name] sortieren und dann nach $zwischen[titel] - aber irgendwie bin ich zu blöd um die Syntax zu verstehen. Geht schon los mit dem ersten sortieren wie spreche ich den "Namen" an? So wird ja nach den vergebenen ids [0],[1], etc. sortiert ... Ich weiß das sind wirkliche Anfängerfragen aber ich habe da ein echtes Verständnisproblem (kann mir die Arrays mit ihren Zuordnungen nicht wirklich vorstellen)...
Sorry, aber wenn Du mir nochmal(!!) helfen könntest, wäre ich Dir echt dankbar!
Grüße,
echo $begrüßung;
$name=trim("$name");
Es ist unsinnig, Variablennamen mit "" einzurahmen. Lass die "" weg.
array\_push($ausgabe[$name],$zwischen);
Statt der Funktion array_push() verwende lieber den Array-Zugriffsoperator []
$ausgabe[$name][] = $zwischen;
Mit dem Sortieren habe ich allerdings noch Probleme. Gehe mal davon aus, dass array_multisort(); zu verwenden ist. Nun möchte ich nach $ausgabe[$name] sortieren und dann nach $zwischen[titel]
Zum einen willst du nach den Array-Keys sortieren, denn der Name ist ja nun als Schlüssel abgelegt, und außerdem die inneren Arrays jedes für sich nach einem der Werte. Das würde ich in Einzelschritte ohne array_multisort() teilen. Der erste Schritt ist eine Sortierung nach Keys, wofür du ksort() verwenden kannst. Dann müsstest du durch das äußere Array laufen und jeweils das innere sortieren, wofür du eine Sortierfunktion mit benutzerdefinierter Vergleichsfunktion verwenden kannst, beispielsweise usort(). Die Vergleichsfunktion übernimmt zwei Parameter, das sind jeweils zwei Array-Elemente, was in deinem Fall zwei Datensätze sind. Von denen willst du die Elemente mit dem Schlüssel 'titel' vergleichen. Dafür kannst du strcmp() nehmen, das dir gleich das für die Vergleichsfunktion passende Ergebnis (-1, 0 oder 1) liefert.
function vergleiche_titel($a, $b) {
return strcmp($a['titel'], $b['titel']);
}
echo "$verabschiedung $name";
Danke Danke Danke
echt super nett!!!
Das mit dem Sortieren nach Namen habe ich hinbekommen, das andere muß ich mir in einer ruhigen Minute nochmal genauer anschauen, peile ich noch nicht so ganz -> nachdem ich das Array ja nach Namen sortieren kann (dank Deiner Hilfe) habe ich die Sortierung nach Titel einfach in der DB Abfrage reingenommen ;-)
Grüße,
Hi,
Statt der Funktion array_push() verwende lieber den Array-Zugriffsoperator []
$ausgabe[$name][] = $zwischen;
Nicht, dass ich das nicht bereits geschrieben haette ...
Und die Pruefung darauf, ob $ausgabe[$name] bereits existiert, kann entfallen. PHP kuemmert sich bei der ersten Zuweisung $ausgabe[$name][] = ... selber darum, $ausgabe[$name] anzulegen, wenn es noch nicht existiert.
MfG ChrisB
echo $begrüßung;
Und die Pruefung darauf, ob $ausgabe[$name] bereits existiert, kann entfallen. PHP kuemmert sich bei der ersten Zuweisung $ausgabe[$name][] = ... selber darum, $ausgabe[$name] anzulegen, wenn es noch nicht existiert.
Mir ging es darum, $ausgabe[$name] explizit als Array zu initialisieren und dann erst Elemente hinzuzufügen. Dies ist im Allgemeinen sinnvoll, um nicht ins Blaue hinein Elemente an vielleicht schon bestehende, früher verwendete und nur nicht aufgeräumte Variablen anzuhängen. In dem Fall kann das jedoch entfallen, wie du richtig angemerkt hast, denn $ausgabe an sich wird ja explizit als leeres Array initialisiert und hat dann natürlich auch keine ungewollten Inhalte. Das if-else-Konstrukt kann also umgeschrieben werden zu:
$ausgabe[$name][] = $zwischen;
echo "$verabschiedung $name";