PHP - Dynamische Keys für multidimensionale Arrays
Hallo mal wieder. Ich suche eine "bessere" Möglichkeit, gegebene Schlüssel an gegebene Positionen in Arrays zu setzen.
Das Eingangsformat sieht so aus, dass ich mehrere ineinander liegende Arrays habe, und diese Inhalte dann durch neuere ersetzen möchte.
Das heißt im Beispiel:
Das währe ja kein Problem, doch leider weiß mein PHP Script per Ajax nur eine Übermittlung mit den Positionen und den Werten bekommt, das sieht dann so aus:
Theoretisch: $profile$position = $wert
Das geht aber logischer weise nicht. Mein Ansatz war dahingehend folgender:
Output:
Die Daten kommen als Array aus der Datenbank, werden dann vom Nutzer bearbeitet, übertragen, gesetzt und wieder in die Datenbank geladen, das Funktioniert alles, auch der Ansatz da oben.
Das Eingangsformat sieht so aus, dass ich mehrere ineinander liegende Arrays habe, und diese Inhalte dann durch neuere ersetzen möchte.
Das heißt im Beispiel:
Hab ich $profile["fields"]["public"]["skype_id"] = "test123"
Möchte ich $profile["fields"]["public"]["skype_id"] = "user123"
Möchte ich $profile["fields"]["public"]["skype_id"] = "user123"
Das währe ja kein Problem, doch leider weiß mein PHP Script per Ajax nur eine Übermittlung mit den Positionen und den Werten bekommt, das sieht dann so aus:
Bekommt Position als $position -> ["fields"]["public"]["skype_id"]
Bekommt den Wert als $wert -> user123
Bekommt den Wert als $wert -> user123
Theoretisch: $profile$position = $wert
Das geht aber logischer weise nicht. Mein Ansatz war dahingehend folgender:
<?php
$json_input = '{
"fields|private|skype": "user123",
"fields|public|twitter": "http://twitter.com/user"
}';
$input = json_decode($json_input, true);
while (list($key, $value) = each($input)) {
$position = str_replace("|",'"]["', $key);
$position = '["' . $position . '"]';
eval("\$dome_profile$position = '$value';");
}
echo "<pre>";
var_dump($dome_profile);
echo "<br>";
print_r($dome_profile);
echo "</pre>";
?>
Output:
array(1) {
["fields"]=>
array(2) {
["private"]=>
array(1) {
["skype"]=>
string(7) "user123"
}
["public"]=>
array(1) {
["twitter"]=>
string(23) "http://twitter.com/user"
}
}
}
Array
(
[fields] => Array
(
[private] => Array
(
[skype] => user123
)
[public] => Array
(
[twitter] => http://twitter.com/user
)
)
)
Nun ist meine Frage: Gibt es eine "schönere" und bessere Lösung, und falls nicht: Packt eval das überhaupt, wenn ich da z.B. Bilder (als Base64) setze?["fields"]=>
array(2) {
["private"]=>
array(1) {
["skype"]=>
string(7) "user123"
}
["public"]=>
array(1) {
["twitter"]=>
string(23) "http://twitter.com/user"
}
}
}
Array
(
[fields] => Array
(
[private] => Array
(
[skype] => user123
)
[public] => Array
(
[twitter] => http://twitter.com/user
)
)
)
Die Daten kommen als Array aus der Datenbank, werden dann vom Nutzer bearbeitet, übertragen, gesetzt und wieder in die Datenbank geladen, das Funktioniert alles, auch der Ansatz da oben.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 275365
Url: https://administrator.de/contentid/275365
Ausgedruckt am: 24.11.2024 um 02:11 Uhr
10 Kommentare
Neuester Kommentar
Hi justanumber44,
also um das mal nach zu vollziehen:
Wenn doch die Daten sowieso als Array aus einer DB/Tabelle kommen, warum bastelst du dir dann aus einem String, der aus drei Begriffen
getrennt durch "|", besteht . . .
. . . erstmal umständlich ein Array und machst dann mit eval eine fragwürdige (siehe http://php.net/manual/de/function.eval.php) Wertezuweisung??
Zum Erstellen eines Arrays gibts doch die gleichnamige Funktion array([string key] => value).
Eine neue Wertezuweisung ist doch dann leicht.
Und hat ein User eine zweite Skype-ID (Zweithandy), so "hängst" du diese einfach an ["private"] dran.
Das hier . . .
. . . müsstest du auch mal näher erläutern.
Auch theoretisch: Eine Tabelle wird abgefragt, die Daten landen zur Bearbeitung in einem Formular. Dann werden die neuen Daten zurückgeschrieben.
Was funktioniert denn genau bei der Übermittlung bzw. Auswertung via Ajax nicht?
Vielleicht kommen wir da ja weiter.
Gruß
Günni
also um das mal nach zu vollziehen:
Zitat von @justanumber44:
. . .
Das Eingangsformat sieht so aus, dass ich mehrere ineinander liegende Arrays habe, und diese Inhalte dann durch neuere ersetzen möchte.
. . .
Die Daten kommen als Array aus der Datenbank, werden dann vom Nutzer bearbeitet, übertragen, gesetzt und wieder in die
Datenbank geladen, das Funktioniert alles, auch der Ansatz da oben.
. . .
. . .
Das Eingangsformat sieht so aus, dass ich mehrere ineinander liegende Arrays habe, und diese Inhalte dann durch neuere ersetzen möchte.
. . .
Die Daten kommen als Array aus der Datenbank, werden dann vom Nutzer bearbeitet, übertragen, gesetzt und wieder in die
Datenbank geladen, das Funktioniert alles, auch der Ansatz da oben.
. . .
Wenn doch die Daten sowieso als Array aus einer DB/Tabelle kommen, warum bastelst du dir dann aus einem String, der aus drei Begriffen
getrennt durch "|", besteht . . .
$json_input = '{
"fields|private|skype": "user123",
"fields|public|twitter": "http://twitter.com/user"
}';
. . . erstmal umständlich ein Array und machst dann mit eval eine fragwürdige (siehe http://php.net/manual/de/function.eval.php) Wertezuweisung??
Zum Erstellen eines Arrays gibts doch die gleichnamige Funktion array([string key] => value).
$input = array("fields" => array("private" => array("skype" => "test123"),
"public" => array("twitter" => "http://www.twitter.com/user")));
Eine neue Wertezuweisung ist doch dann leicht.
$input["fields"]["private"]["skype"] = "user123";
Und hat ein User eine zweite Skype-ID (Zweithandy), so "hängst" du diese einfach an ["private"] dran.
$input["fields"]["private"]["skype2"] = "user784392";
Das hier . . .
Das währe ja kein Problem, doch leider weiß mein PHP Script per Ajax nur eine Übermittlung mit den Positionen und den Werten bekommt, das sieht dann so aus:
Das geht aber logischer weise nicht.
Bekommt Position als $position -> ["fields"]["public"]["skype_id"]
Bekommt den Wert als $wert -> user123
Theoretisch: $profile$position = $wert
Bekommt den Wert als $wert -> user123
Theoretisch: $profile$position = $wert
Das geht aber logischer weise nicht.
. . . müsstest du auch mal näher erläutern.
Auch theoretisch: Eine Tabelle wird abgefragt, die Daten landen zur Bearbeitung in einem Formular. Dann werden die neuen Daten zurückgeschrieben.
Was funktioniert denn genau bei der Übermittlung bzw. Auswertung via Ajax nicht?
Vielleicht kommen wir da ja weiter.
Gruß
Günni
Hi,
also wenn ich das Json richtig verstanden habe, dann sind da ja zwischen jedem Wert die '|' dazwischen, die du per str_replace trennst.
Warum machst du dann nicht einfach ein 4D Array, das aus einem Zähler für den Eintrag, den Kennzeichnern und dem Wert besteht?
Das ließe sich wunderbar mit explode für '|' regeln.
also quasi
Wird halt ein klein wenig abartig wenn du dann noch Sortierungen machen willst, weil ab 3 Dimensionen steig ich da einfach aus geistig :D
Liebe Grüße und viel Erfolg
Larmina
also wenn ich das Json richtig verstanden habe, dann sind da ja zwischen jedem Wert die '|' dazwischen, die du per str_replace trennst.
Warum machst du dann nicht einfach ein 4D Array, das aus einem Zähler für den Eintrag, den Kennzeichnern und dem Wert besteht?
Das ließe sich wunderbar mit explode für '|' regeln.
also quasi
<?php
$i = 0;
foreach ($jsoninput as $value)
{
$typ_temp = explode('|', $value);
$dim1 = $typ_temp;
$dim2 = $typ_temp[1];
$dim3 = $typ_temp[2];
$array[$i][$dim1][$dim2][$dim3] = $Wertdendualswerthast;
$i++;
}
?>
Liebe Grüße und viel Erfolg
Larmina
Hi Jonas,
wenn du es komplett Dynamisch haben willst, dann hab ich dir hier grade eine kleine Funktion geschrieben.
Du musst dann halt den Wert den du am Ende übergeben willst auch als Arraykey setzen, und dann die arrays durchlaufen.
Oder du dröselst dir einen Weg in der Funktion noch einen Wert zu übergeben, was ich jetzt ohne größeren Aufwand nicht hinbekommen habe.
Liebe Grüße
Larmina
wenn du es komplett Dynamisch haben willst, dann hab ich dir hier grade eine kleine Funktion geschrieben.
Du musst dann halt den Wert den du am Ende übergeben willst auch als Arraykey setzen, und dann die arrays durchlaufen.
Oder du dröselst dir einen Weg in der Funktion noch einen Wert zu übergeben, was ich jetzt ohne größeren Aufwand nicht hinbekommen habe.
function array_add_dimensions($array, $arr_dims)
{
if(count($arr_dims) === 0)
{
return $array;
}
$dim = array_shift($arr_dims);
$array[$dim] = array();
$array[$dim] = array_add_dimensions($array[$key], $arr_dims);
return $array;
}
$arr_dims = array('profil','private','skypeid','foobar',); // Hier fügst du die Werte ein die vom JSON kommen, geht ja auch dynamisch via explode und foreach.
$array = array();
print_r(array_add_dimensions($array, $arr_dims));
Liebe Grüße
Larmina
Zitat von @justanumber44:
Naja, es ist eigentlich so, dass in einem PHP Dokument automatisiert Einträge erstellt werden, in einer Each Funktion.
Übergeben wird, eben via json, was wo hin gehört. Ich muss eben in ein vorhandenes Array zu den passenden Positionen die
Einträge speichern:
Client: "test" -> fields -> public -> skype_id - Der sagt also, wo es hin geht
Server: $input["fields"]["public"]["skype_id"] -> "test"
Das Problem ist, das ich leider nicht einfach sagen kann, wo er den Wert einspeichern soll außer eval
Ich muss anhand eines Strings die Position eines Arrays bestimmen, um dort schlussendlich den Wert zu sichern
Naja, es ist eigentlich so, dass in einem PHP Dokument automatisiert Einträge erstellt werden, in einer Each Funktion.
Übergeben wird, eben via json, was wo hin gehört. Ich muss eben in ein vorhandenes Array zu den passenden Positionen die
Einträge speichern:
Client: "test" -> fields -> public -> skype_id - Der sagt also, wo es hin geht
Server: $input["fields"]["public"]["skype_id"] -> "test"
Das Problem ist, das ich leider nicht einfach sagen kann, wo er den Wert einspeichern soll außer eval
Ich muss anhand eines Strings die Position eines Arrays bestimmen, um dort schlussendlich den Wert zu sichern
Hi justanumber44,
also irgendwie erschließt sich mir nicht der Sinn von deinem Vorhaben.
Es werden . . . in einem PHP Dokument automatisiert Einträge erstellt . . .
In einer Each Funktion ???. Erklärung bitte.
Übergeben wird, eben via json, was wo hin gehört.
Client: "test" -> fields -> public -> skype_id - Der sagt also, wo es hin geht
Client: "test" -> fields -> public -> skype_id - Der sagt also, wo es hin geht
Der sagt also, wo es hin geht. Wer ist "Der"?. Wie und wo sagt "Der" dir, "wo es hin geht"?
Erkläre das doch auch mal genauer. Was wird wie via json übergeben ?? Vielleicht postest du mal ein Script ??
Das Problem ist, das ich leider nicht einfach sagen kann, wo er den Wert einspeichern soll außer eval
Ich muss anhand eines Strings die Position eines Arrays bestimmen, um dort schlussendlich den Wert zu sichern
Ich muss anhand eines Strings die Position eines Arrays bestimmen, um dort schlussendlich den Wert zu sichern
Das widerspricht sich doch irgendwie, oder? Du kannst nicht sagen, wo ein Wert gespeichert werden soll,
bestimmst aber anhand eines Strings, dass ein Wert dann doch irgendwo gespeichert wird.
Was du an Larminas Funktionsergebnis als "coolen Ansatz" beschreibst . . .
Array
(
[profil] => Array
(
[private] => Array
(
[skypeid] => Array
(
[foobar] => Array
(
[Noch_ein_Array] => Array
(
[Und_noch_ein_Array] => Array
(
[Ein_letztes_Array] =>
)
)
)
)
)
)
)
Du willst doch nicht ernsthaft sagen, dass du das in einer DB-Tabelle speicherst (speichern willst)???
Ein Abfrageergebnis einer Datenbank ist in der Regel immer ein Array. Und in der Regel bestehen die Array-Schlüssel
aus den Namen der jeweiligen Tabellenspalten. Also weiß ich doch anhand der Array-Schlüssel, auch wieder in der Regel,
wo ich Werte in eine Tabelle zurückschreibe. Und auch wenn mir die Werte via json übergeben werden, gibts auch hier für
"coole Ansätze", Elementpositionen in einem Array zu finden und zu beschreiben.
Deshalb auch meine Frage im ersten Kommentar: Was funktioniert denn genau bei der Übermittlung bzw. Auswertung via Ajax nicht?
Gruß
Günni
Hi justanumber44,
dauert i.M. immer etwas, bis ich mal zum Antworten komme.
Zum Ändern eines Wertes könntest du viell. die Function array_walk_recursive verwenden??
Geht aber, glaub' ich, wirklich nur zum Ändern von bestehenden Werten. Die Schlüssel fields, private, public z.B. werden gar nicht ausgegeben.
Wenn du hier PHP-Manual im Suchfeld array eingibst, so werden da noch aufgelistet . . .
- ArrayAccess
- ArrayIterator
- ArrayObject
Eventuell wäre da noch was dabei, was dir hilft, Arrays zu händeln. Hab' ich mir aber auch noch nie genauer angeguckt.
Gruß
Günni
PS.:
Sowas ähnliches wie cd auf der Konsole für Arrays gibts eigentlich schon.
current() — Liefert das aktuelle Element eines Arrays
end() - Positioniert den internen Zeiger eines Arrays auf dessen letztes Element
key() - Liefert einen Schlüssel eines Arrays
each() - Liefert das aktuelle Paar (Schlüssel und Wert) eines Arrays und rückt den Arrayzeiger vor
prev() - Setzt den internen Zeiger eines Arrays um ein Element zurück
reset() - Setzt den internen Zeiger eines Arrays auf sein erstes Element
next() - Rückt den internen Zeiger eines Arrays vor
Geht aber leider nur, soweit ich das probiert habe, auf einer Dimension in einem Array.
dauert i.M. immer etwas, bis ich mal zum Antworten komme.
Schlussendlich suche ich nach einer Möglichkeit, wie beim Verzeichniswechsel, in einem Array vor zu wandern, wie als würde ich versuchen von der Festplatte in einen
bestimmten, mir bekannten Unterordner zu gelangen, um dort was zu speichern, nur eben auf ein Array bezogen, das bereits befüllt ist.
bestimmten, mir bekannten Unterordner zu gelangen, um dort was zu speichern, nur eben auf ein Array bezogen, das bereits befüllt ist.
Zum Ändern eines Wertes könntest du viell. die Function array_walk_recursive verwenden??
<?php
$input = array("fields" => array("private" => array("skype" => "test123"),
"public" => array("twitter" => "http://www.twitter.com/heinz")));
/* Callback zur Ausgabe */
function array_print($item, $key){
echo "$key = $item<br>";
}
/* Callback zum Ämdern */
function array_alter(&$item, $key, $user_data){
if($key == key($user_data)){
$item = $user_data[key($user_data)];
}
}
echo "<h4>Vorher . . . </h4>";
/* Funktionsaufruf mit Callback zur Ausgabe*/
array_walk_recursive($input, 'array_print');
/*
* Neue Daten
*/
$data_neu = array("skype" => "user456");
/* Oder . . . */
// $data_neu = array("twitter" => "http://www.twitter.com/willi");
/* Funktionsaufruf mit Callback zum Ändern */
array_walk_recursive($input, 'array_alter', $data_neu);
echo "<h4>Nachher . . . </h4>";
/* Funktionsaufruf mit Callback zur Ausgabe */
array_walk_recursive($input, 'array_print');
?>
Geht aber, glaub' ich, wirklich nur zum Ändern von bestehenden Werten. Die Schlüssel fields, private, public z.B. werden gar nicht ausgegeben.
Wenn du hier PHP-Manual im Suchfeld array eingibst, so werden da noch aufgelistet . . .
- ArrayAccess
- ArrayIterator
- ArrayObject
Eventuell wäre da noch was dabei, was dir hilft, Arrays zu händeln. Hab' ich mir aber auch noch nie genauer angeguckt.
Gruß
Günni
PS.:
Sowas ähnliches wie cd auf der Konsole für Arrays gibts eigentlich schon.
current() — Liefert das aktuelle Element eines Arrays
end() - Positioniert den internen Zeiger eines Arrays auf dessen letztes Element
key() - Liefert einen Schlüssel eines Arrays
each() - Liefert das aktuelle Paar (Schlüssel und Wert) eines Arrays und rückt den Arrayzeiger vor
prev() - Setzt den internen Zeiger eines Arrays um ein Element zurück
reset() - Setzt den internen Zeiger eines Arrays auf sein erstes Element
next() - Rückt den internen Zeiger eines Arrays vor
Geht aber leider nur, soweit ich das probiert habe, auf einer Dimension in einem Array.