String in Mehrdimensionales Array wandeln

Delmar

Delmar

Aktives Mitglied
Thread Starter
Dabei seit
28.09.2002
Beiträge
829
Reaktionspunkte
1
Hallo,

ich habe folgendes Problem: Ich habe in einer Datenbanktabelle zwei Felder,
die jeweils wie folgt gefüllt sind

Code:
Datensatz 1:
Feld1: "firewall[0][ip]"
Feld2: "125.125.125.125"

Datensatz 2:
Feld1: "firewall[0][port]"
Feld2: "21"

Datensatz 3:
Feld1: "firewall[1][ip]"
Feld2: "125.125.125.126"

Datensatz 4:
Feld1: "firewall[1][port]"
Feld2: "80"

Ich möchte aus diesen Datensätzen nun ein mehrdimensionales Array erstel-
len, das wie folgt aussieht:

Code:
["firewall"] { 
    [0]=> { 
        ["ip"]=> "125.125.125.125" 
        ["port"]=> "21" 
    } 
    [1]=> { 
        ["ip"]=> "125.125.125.126" 
        ["port"]=> "80" 
    } 
}

Ich möchte also Feld1 in seine einzelnen Elemente zerteilen und als Schlüs-
sel für das mehrdimensionale Array verwenden.

Ich bin schon den ganzen Nachmittag am Rumprobieren, habe bis jetzt aber
noch keine elegante Lösung. Hat jemand eine Idee? Gibt es evtl. eine Array-
Funktion, die mir dabei helfen könnte?


Vielen Dank schon mal.
 
Dazu erstmal eine wahrscheinlich blöde Frage.

Wie sind die Felder Deiner Tabelle benannt, bzw., wieso hast Du in der Tabelle nicht einfach ein Feld "ip" und ein Feld "port" und da steht das dann jeweils drin ?

Liegt das daran, das in der Tabelle beliebige Werte drin liegen können ?

Davon mal ab, könnte man folgendes machen.
Also Du hast deine Datenbankabgrafe und da ja dann eine Stelle, wo Du in einer Schleiffe auf die Ergebnisse aus der Datenbank zugreifst:
<?php
$result = mysql_query("SELECT feld1, feld2 FROM myTable");

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$$row["feld1"] = $row["feld2"];
}
?>

Weißt Du, was ich meine ?


Update:
Mmmh, habe das gerade mal getestet.
Das geht wohl doch nicht so wi oben gedacht.
Aber die Idee war gut. :D
 
Ne, aber bei solchen Fragen und im Forum Webprogrammierung gehe ich erstmal von PHP aus. :D
 
Warum? Ich mach das alles in Perl. Da geht sowas nämlich sehr einfach ;).
 
Stimmt, Perl könnte auch sein.
Wie würdest Du das da machen ?

Mit eval(), oder doch den String ausinandernehmen, oder ganz anders ?
 
Mmmh, habe das gerade mal getestet.
Das geht wohl doch nicht so wi oben gedacht.
Aber die Idee war gut. :D

Ich hatte gerade genau die gleiche Idee... aber auch bei meinem Test hat's nicht funktioniert...
 
Stimmt, Perl könnte auch sein.
Wie würdest Du das da machen ?
...
Ich kann die Randbedingungen nicht, aber ich denke ich würde einfach die Datenbank anders aufbauen. Sieht ja sehr nach einer 1:1 Beziehung aus.
 
Zuletzt bearbeitet:
:)

Deswegen auch am Anfang meine Frage, warum das so sein muß mit den Feldern.
Das ist ja schon irgendwie fies so. :)
 
Edit: War Blödsinn. Sorry.
Die Datenstruktur in der Tabelle ist wirklich SEHR schlecht gewählt.
 
Vielleicht würde ja so etwas schon reichen:
Code:
my %firewall = ('125.125.125.125' => 21,
         '125.125.125.126' => 80,
         );
usw.
 
Ok, der TE hat ja schon eingesehen, das die Struktur ungünstig war, aber mit der Kraft des regulären Ausdrucks habe ich doch noch eine Lösung gefunden. :D

It just works. :)
<?php
mysql_connect("localhost", "root", "") or die("Keine Verbindung möglich: " . mysql_error());
mysql_select_db("test");

$result = mysql_query("SELECT feld1, feld2 FROM variablen");
$firewall = array();

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

if(ereg(".*\[(.*)\]\[(.*)\]", $row["feld1"], $regs)){
$firewall[$regs[1]][$regs[2]] = $row["feld2"];
}

}

print_r($firewall);
?>

Array
(
[0] => Array
(
[ip] => 125.125.125.125
[port] => 21
)

[1] => Array
(
[ip] => 125.125.125.126
[port] => 80
)

)
 
  • Gefällt mir
Reaktionen: Delmar
Ich glaub, das geht nur, indem man entweder
a) den jeweiligen Wert aus Feld 1 aufsplittet und anhand der einzelnen Teile das Ergebnis-Array anlegt; oder
b) wie bereits gesagt: die DB-Struktur neu anlegt.

Wobei ich b) für die bessere Lösung halte; Version a) wäre ein ziemliches Gemauschel.
 
aber mit der Kraft des regulären Ausdrucks habe ich doch noch eine Lösung gefunden. :D

Kannst Du mal aufhören, ständig das gleiche zu denken wie ich?
;)

Das meinte ich mit dem »aussplitten«; nur dass Du direkt eine fertige Lösung präsentiert hast...
 
Erstmal danke für die vielen Antworten.

Zu der ersten Frage: Ja, es handelt sich um PHP. Hatte ich leider vergessen
zu erwähnen.

Die Datenbankstruktur mag auf den ersten Blick total dämlich und ineffizient
erscheinen, macht für mein Projekt Sinn. Der Grundaufbau der Tabelle ist
wie schon vermutet:

Feld1 = "Parametername"
Feld2 = "Wert"

Ich benötige in diesem Projekt die maximale Flexibilität. Leider führt das
auch zu solch merkwürdigen Einträgen wie in Feld1.

Ich bin z.Zt. auch auf dem Weg des "Zersplittens", da das aber nicht gerade
die elegantestes Lösung ist, war die Frage, ob es evtl. eine String- oder
Array-Funktion in PHP gibt, die mir den String, der ja bereits wie ein Schlüs-
sel aufgebaut ist, auch als einen solchen umwandelt.
 
Optimal ist die Struktur nicht.

Da würde ich eventuell eher hergehen (wenn das so bleiben muß) und das so ändern, das in feld1 ein bezeichner wie z.B. "firewall" gespeichert wird und in Feld zwei das serialisierte komplette Array.

Dann kann Du über den begriff "firewall" auf das entsprechende Feld zugreifen und mußt das Ergebnis aus feld2 dann nur noch deserialisieren und hast Dein Array.

Mann könnte in diesem Zuge auch noch ein drittes Feld einführen, wo der Typ drinsteht (String, Array), damit Du weißt, ob Du das Ergebnis
deserialisieren mußt,oder ob da nur ein String zurückkommt.

Aber das ist alles gebastel und nicht optimal.

Wenn möglich solltest Du doch an der Tabellenstruktur drehen.
 
Im Gunde ist das ja eine alte Geschichte. Den Inhalt einer Variablen als Variablenname nehmen. In Perl könnte man hier einen Hash anlegen in dem dann die eigentlichen Werte z.B. als anonymer Array gespeichert werden könnten. Die keys können als Variable angegeben werden.
Ich persönlich versuche so etwas zu vermeiden.
 
Ich hab' mal ein wenig in Perl herumgespielt.
Da könnte man z.B. folgende Datenstruktur anlegen (Hash von Hashes):
Code:
#!/usr/bin/perl
#
use strict;
use warnings;

my %firewall = (  0 => {  ip    => "192.168.100.10" ,
                          port  => "21"},
                  1 => {  ip    => "192.168.100.15",
                          port  =>  "80"}
                );  
print "IP:\t".$firewall{0}{ip}."\n";
print "Port:\t".$firewall{0}{port}."\n";
Lässt sich sicher auf PHP übertragen.

oder so (Array von anonymen Hash Referenzen)
Code:
#!/usr/bin/perl
#
use strict;
use warnings;

my @firewall = (  {   ip    => "192.168.100.10" ,
                          port  => "21"},
                  {   ip    => "192.168.100.15",
                          port  =>  "80"}
                );  
print "IP:\t".$firewall[0]->{ip}."\n";
print "Port:\t".$firewall[0]->{port}."\n";
 
Zuletzt bearbeitet:
Hallo zusammen,

noch mal vielen Dank für Eure Lösungsvorschläge. Ich habe aber inzwischen herausge-
funden, dass die (Array-)Struktur mir an anderer Stelle noch mehr Probleme macht, als
sie hilft. Ich habe das Konzept daher verworfen und mir damit beholfen, dass die
Parameternamen nun wie folgt aussehen:

Code:
firewall_0_ip
firewall_0_port
firewall_1_ip
firewall_1_port

Mittels der explode() Funktion extrahiere ich mir nun die einzelnen Elemente.

Das Problem war, dass ich die Paramenternamen als Namen für Input-Felder verwende.
Dies wiederum hat bei der Variante firewall[0][ip] dazu geführt, dass die $_POST Vari-
able diese Felder auch als multidimensionales Array übergeben hat. In der Speicherung
der Daten benötige ich allerdings wieder den Parametername als zusammengesetzten
String "firewall[0][ip]". Alles in allem also ein ziemliches Hin und Her.

Damit ihr mich nicht für völlig bekloppt haltet, habe ich mal einen Ausschnitt des betrof-
fenen Formulars angehängt. Dadurch wird es vielleicht deutlicher. In diesem Fall handelt
es sich um die Felder:

Code:
externalDNS_0_ip
externalDNS_0_port
externalDNS_1_ip
externalDNS_1_port

Über das + und das - am Ende einer Zeile kann man dann entsprechend ein weiteres Element für
"External DNS" hinzufügen bzw. ein bestehendes wieder entfernen.

Eine bessere Lösung für diese Anforderung ist mir leider nicht eingefallen.
 

Anhänge

  • Picture 2.jpg
    Picture 2.jpg
    3,4 KB · Aufrufe: 59
Also, ehrlich gesagt, kapiere ich das immer noch nicht so ganz...


Delmar;4832127Ich habe aber inzwischen herausgefunden schrieb:
Ich bin weiterhin der Meinung, dass die Datenbankstruktur das eigentlich Problem darstellt.
Warum nicht eine DB, die in etwa der folgenden Struktur entspricht?
Code:
TABLE externalDNS

id  |  ip             | port
------------------------------
1   | 125.125.125.125 | 21
------------------------------
2   | 125.125.125.126 | 80


Das zugehörige Formular sieht dann etwa so aus:
HTML:
<form>
<input type="text" name="ip[1]" value="125.125.125.125">
<input type="text" name="port[1]" value="21"><br>

<input type="text" name="ip[2]" value="125.125.125.126">
<input type="text" name="port[2]" value="80"><br>

<!-- für neue Einträge: -->
<input type="text" name="ip[]" value="">
<input type="text" name="port[]" value=""><br>

<input type="text" name="ip[]" value="">
<input type="text" name="port[]" value=""><br>

...

</form>

Mit dieser Grundstruktur sollte sich sowohl das Auslesen und Bearbeiten, als auch das Anlegen neuer Einträge problemlos behandeln lassen...
 
Zurück
Oben Unten