Jeden existierenden Wert eines Arrays bearbeiten
Anatol
- php
Hallo!
Ich vermute zwar, dass eine Frage in diese Richtung schon einmal gestellt wurde, ich habe im Archiv aber leider nichts finden können. Darum geht´s:
Ich möchte in einem mehrdimensionalen Array jeden existierenden Wert einzeln bearbeiten und mit geänderten Werten wieder abspeichern. Der Array soll auch "unvorhersehbare" Formen annehmen können. Damit meine ich, dass er in Länge und Dimensionalität völlig unterschiedlich ausfallen kann.
Ich schätze genau hier liegt irgendwo das Problem: Ich erzeuge eine Endlosschleife, aber ich erkenne nicht, warum.
Wenn es irgendeine Andere Möglichkeit gibt, alle Werte eines mehrdimensionalen Arrays durchzugehen, dann wäre das sicher auch die sauberere Lösung. Ich habe aber nichts gefunden. Kennt jemand eine Möglichkeit?
Ansonsten wäre ich auch sehr dankbar dafür, wenn mir jemand bei meiner Endlosschleife auf die Sprünge helfen würde. Im Anschluß befindet sich ein vereinfachtes Script, das das Problem schildern sollte: Alle Werte des Arrays sollen in diesem Beispiel in html entities geändert oder zumindest dahingehend überprüft werden:
<?
############################################################
############################################################
function processArray($array) {
if ( is_array($array) ) {
for ( $i = 0; $i < count($array); $i++ ) {
$array[$i] = processArray($array[$i]);
}
} else {
$array = htmlentities($array);
}
return $array;
}
############################################################
// ich erstelle einen mehrdimensionalen "unberechenbaren" Array:
$test = array (
"A" => array (
1 => array (
"eins" => "Umlaut Ä",
"zwei" => "Umlaut Ö",
"drei" => "Umlaut Ü"
),
2 => array (
"irgend" => "Straße",
"etwas" => "Müsli",
"etc" => "Öl",
"blabla" => "Blindtext, ähm ...",
1 => array (
"name" => "irgendein Inhalt, äöüß"
),
),
),
"B" => array (
1 => array (
"eins" => "Umlaut Ä, schonwieder",
"zwei" => "Umlaut Ö, egal was",
"drei" => "Umlaut Ü, Inhalt!"
),
),
);
echo "<hr>vorher:<hr><pre>";
print_r ($test);
echo "</pre>";
// Funktion aufrufen:
$test = processArray($test);
echo "<hr>nachher:<hr><pre>";
print_r ($test);
echo "</pre>";
?>
Was mache ich falsch?
Vielen Dank schonmal.
Schöne Grüße
Anatol Bogun
echo $begrueszung;
Ich möchte in einem mehrdimensionalen Array
Es gibt keine mehrdimensionalen Arrays in PHP. Man kann Arrays maximal verschachtelten.
jeden existierenden Wert einzeln bearbeiten
schalte alle Fehlermeldungen (inklusive Notizen) ein, dann siehst du, was schiefläuft.
Schalte dazu das error_reporting auf E_ALL
Und anschließend kannst du dich mit foreach vertraut machen.
echo "$verabschiedung $name";
Hello,
Es gibt keine mehrdimensionalen Arrays in PHP. Man kann Arrays maximal verschachtelten.
Na Du traust Dich ja was. Das wollte ich neulich eigentlich auch schreiben, habe aber schon den Sturm der Entrüstung aufziehen sehen. Es gibt in PHP eigentlich nur eine einzige Sorte Arrays, und die nennt man auch Zeichenkette. Alle die "Array" genannt werden, sind entweder verkettete Listen oder sogar Baumstrukturen.
Der Begriff des Arrays steht eigentlich für die Anreihung gleichartiger Elemente oder Substrukturen im Speicher. Die Elemente der PHP-"Arrays" können aber alle unterschiedlich sein, erfüllen also die erste Grundregel für Arrays bereits nicht.
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
echo $begrueszung;
Der Begriff des Arrays steht eigentlich für die Anreihung gleichartiger Elemente oder Substrukturen im Speicher.
Das stimmt doch bei PHP. Die sind doch alle vom Type mixed... :-)
echo "*duck und wech* $name";
Hallo!
Ich möchte in einem mehrdimensionalen Array jeden existierenden Wert einzeln bearbeiten und mit geänderten Werten wieder abspeichern. Der Array soll auch "unvorhersehbare" Formen annehmen können. Damit meine ich, dass er in Länge und Dimensionalität völlig unterschiedlich ausfallen kann.
Wenn Du PHP5 verwenden kannst, empfielt sich hier die Verwendung von array_walk_recursive().
Wenn Dir noch kein PHP5 zur Verfügung steht wird es ein klein wenig komplizierter, da wirfst Du am besten mal einen Blick auf array_walk(), vor allem auch auf die User-Kommentare dort!
$array[$i] = processArray($array[$i]);
Warum das eine Endlosschleife gibt sehe ich nicht auf den ersten Blick, ist bei rekursiven Funktionen aber ein "beliebtes" Problem und nicht immer ganz einfach zu debuggen.
Aber abgesehen davon funktioniert das so nur mit nummerischen Schlüsseln, wenn Schlüssel fehlern können noch nichtmal damit.
// Funktion aufrufen:
$test = processArray($test);
Es gibt mehrere Möglichkeiten, ein Beispiel für PHP5:
<?php
function array_htmlentities (&$item, $key) {
$item = htmlentities($item);
}
array_walk_recursive($test, 'array_htmlentities');
?>
Ein Beispiel für PHP4:
<?php
function array_htmlentities(&$item, $key) {
if (is_array($item)) {
array_walk($item, 'array_htmlentities');
}
else {
$item = htmlentities($item);
}
}
array_walk($test, 'array_htmlentities');
?>
Oder ohne array_walk():
<?php
function array_htmlentities(&$item){
if (is_array($item)) {
foreach ($item as $key => $value) {
$item[$key] = array_htmlentities($value);
}
}
else {
$item = htmlentities($item);
}
return $item;
}
array_htmlentities($test);
?>
Beachte dass hierbei jeweils keine Kopie von $test verwendet wird, sondern direkt die "originalen" Daten in $test verändert werden.
Grüße
Andreas
echo $begrueszung;
Warum das eine Endlosschleife gibt sehe ich nicht auf den ersten Blick,
Aber auf den zweiten Blick ist es mir dann aufgefallen...
ist bei rekursiven Funktionen aber ein "beliebtes" Problem ...
Soweit kommt es gar nicht, jedenfalls nicht tiefer als eine Ebene.
Am Anfang haben wir ein Array mit den beiden Keys 'A' und 'B'.
In einer for-Schleife, die bei 0 anfängt und bei count($array) (= 2) abbrechen soll, wird auf das Array-Element mit dem Key 0 zugegriffen. Dieses existiert nicht, PHP wirft eine Notice und legt gleichzeitig dieses Element an und begibt sich mit diesem in eine weitere Inkarnation von processArray(). Dort trifft is_array() nicht zu, wir landen im else-Zweig und kehren wieder zurück.
Beim nächsten Schleifendurchlauf ergibt count($array) mittlerweile 3, usw. usf. bis die "Allowed memory size of ... bytes exhausted"
echo "$verabschiedung $name";
Hallo Andreas, hallo $name // dedlfix?
Vielen Dank,
ihr habt mir sehr geholfen. Nachdem ich mich wie dedlfix vorgeschlagen hat mit "foreach" beschäftigt habe, bin ich im Grunde auf dieselbe Lösung gekommen, wie Andreas.
Andreas: Beachte dass hierbei jeweils keine Kopie von $test verwendet wird, sondern direkt die "originalen" Daten in $test verändert werden.
Danke für diesen Hinweis. Ich habe nicht gewußt, dass ich mit "&" eine Referenz an die Variable übergeben kann, und die Funktion somit den Orginalwert verändert.
[Link:http://de.php.net/manual/en/functions.arguments.php#functions.arguments.by-reference]
Muss ich bisher überlesen haben. Das ist aber sehr nützlich.
Also vielen Dank! Schöne Grüße!
Anatol
Zur Ergänzung: Folgendes Script funktioniert dann:
<?
############################################################
// Diese Beispielfunktion wandelt alle Werte eines Arrays in HTML entities um
function processArray(&$item){
if (is_array($item)) {
foreach ($item as $key => $value) {
$item[$key] = processArray($value);
}
} else {
$item = htmlentities($item);
}
return $item;
}
############################################################
// ich erstelle einen mehrdimensionalen Array:
$test = array (
0 => array (
0 => array (
"eins" => "Umlaut Ä",
"zwei" => "Umlaut Ö",
"drei" => "Umlaut Ü"
),
1 => array (
"irgend" => "Straße",
"etwas" => "Müsli",
"etc" => "Öl",
"blabla" => "Blindtext, ähm ...",
0 => array (
"name" => "irgendein Inhalt, äöüß"
),
),
),
1 => array (
1 => array (
"eins" => "Umlaut Ä, schonwieder",
"zwei" => "Umlaut Ö, egal was",
"drei" => "Umlaut Ü, Inhalt!"
),
),
);
echo "<hr>vorher:<hr><pre>";
print_r ($test);
echo "</pre>";
// Funktion aufrufen:
processArray($test);
echo "<hr>nachher:<hr><pre>";
print_r ($test);
echo "</pre>";
?>
echo $begrueszung;
Wenn du schon Referenzen verwendest, dann sollte das auch sinnvoll sein:
function processArray(&$item){
Hier übernimmst du eine Referenz
if (is_array($item)) {
foreach ($item as $key => $value) {
$item[$key] = processArray($value);
auf $value, das eine Kopie den Wertes von $item[$key] ist. Das Ergebnis kopierst du dann wieder in das Original. Arbeite doch gleich mit dem Original:
processArray($item[$key]);
}
} else {
$item = htmlentities($item);
}
return $item;
Das return brauchst du dann nicht mehr.
}
echo "$verabschiedung $name";