PHP Mal wieder "[] operator not supported for strings"

mischaef

Kassettenkind
Teammitglied
Registriert
Aug. 2012
Beiträge
6.147
Moin zusammen,

ich habe ein PHP-Script, bei welchen an mehrern Stellen eingegebene Daten auf ihre Richtigkeit überprüft werden sollen. Die dabei als fehlerhaft empfundenen Eingaben werden in eine Session gespeichert, damit sie in einem Formular noch einmal ausgegeben und korrigiert werden können. Das klappt bereits recht gut.

Jetzt möchte ist aus Testzwecken überprüfen, an welchen Stellen welche provozierten Fehler abgefangen werden. Dazu müsste ich lediglich einen String ("Fehler bei ... abgefangen") mit in die Session schreiben - doch dabei bekomme ich immer wieder die Fehlermeldung "[] operator not supported for strings". Die Eingabe soll in $_SESSION["rueckgabe"] gespeichert werden, die ich vorher auch mittels $_SESSION["rueckgabe"] = array(); als Feld deklariert habe. Die anderen Eingaben werden per $_POST in die Session eingefügt. Bisher schaut das ganze so aus:


Code:
$_SESSION["rueckgabe"][] = "<p>Fehler bei ... abgefangen</p>";
$_SESSION["datum_tag"][] = $_POST["datum_tag"][$i];
$_SESSION["datum_monat"][] = $_POST["datum_monat"][$i];
$_SESSION["datum_jahr"][] = $_POST["datum_jahr"][$i];
$_SESSION["betrag"][] = $_POST["betrag"][$i];
$_SESSION["kommentar"][] = $_POST["kommentar"][$i];

Ich habe jetzt einiges Probiert...am Ende wäre ich sogar zufrieden gewesen, wenn das Feld lediglich eine Nummer speichern würde, anhand der ich die Position des Fehlers lokalisieren könnter - immer wieder die gleiche Fehlermeldung. Ich hab es auch mit array_push () versicht, keinen Unterschied. Auch habe ich versucht, die Eingabe in ein Feld zu schreiben und das dann an die Session zu übergeben - ebenfalls keine Änderung.

Ich frage mich nur, warum der String bei den anderen Eingaben genommen wird. Oder geht es hier gar nicht um den String, also die Form des Inhaltes an sich, sondern darum, dass ich ein array mit etwas füllen will, was kein array ist? Die $_POST-Eingaben kommen ja aus einem Feld.

Ich wäre für jeden Hinweis, in welche Richtung ich mal schauen soll, dankbar.

Gruß

Michael
 
Zuletzt bearbeitet:
Nein, hatte ich nicht, da die anderen Felder ja in die Session geschrieben werden und ich daher davon ausgegangen bin, dass es nicht nötig ist.

Habs aber mal getestet, kommt jedoch immer noch die gleiche Fehlermeldung.
 
Ich würde an deiner Stelle eher mal print_r($_POST); machen, ich würde vermuten dass zB $_POST['betrag'] kein Array ist sondern vllt einfach nur ein String oder so...
 
Nein, mit dem POST werden mehrere Einträge übertragen. Das ganze kommt aus einem Eingabeformular mit denen für 10 Einträge auf einmal die Eingabefelder gefüllt werden können und mittels "[]" als Feld ausgewiesen sind. Die Inhalte werden auch in die Datenbank geschrieben, das funktioniert alles - und der Teil ist ja nicht das Problem. Ich habe mit $_SESSION["rueckgabe"] ja ein array, was eben nicht per $_POST, sondern direkt gefüllt wird.

Ich habe es aber mal mit print_r bei der Session ausprobiert, und da wird bei $_SESSION["rueckgabe"] "Array()" angezeigt.
 
mischaef schrieb:
Ich habe es aber mal mit print_r bei der Session ausprobiert, und da wird bei $_SESSION["rueckgabe"] "Array()" angezeigt.

Probier mal var_dump($_SESSION) bevor du da das Zeug versuchst reinzuschreiben vllt steht in $_SESSION['rueckgabe'] vorher schon ein string drinne oder leerer String, dann würde $_SESSION['rueckgabe'][] quasi auf einen String ausgeführt und $_SESSION['rueckgabe'] = array() vorher sollte regeln. Ist halt schwer zu sagen ohne die Inhalte zu kennen, wenns geht paste einfach mal was var_dump bei Session und Post ausgibt....
 
  • Gefällt mir
Reaktionen: Guru-Meditation
Wenn ich die Aufrufe an der Stelle einfüge, an der in die Session schreiben will kommt folgendes:

/volume1/web/index.php:187:array(7) {
'rueckgabe' => array(0) { }
'datum_tag' => array(2) { [0] => string(0) "" [1] => string(0) "" }
'datum_monat' => array(2) { [0] => string(0) "" [1] => string(0) "" }
'datum_jahr' => array(2) { [0] => string(0) "" [1] => string(0) "" }
'betrag' => array(2) { [0] => string(0) "" [1] => string(0) "" }
'kommentar' => array(2) { [0] => string(0) "" [1] => string(0) "" }
'fehler' => string(8) "Fehler 1"}

Ich habs für die Übersicht ein wenig formatiert, die Felder sind normalerweise auch gefüllt, ich musste jetzt nur leere abschicken, damit das Abfangen der Fehler greift.

var_dump($_SESSION)["rueckgabe"];
/volume1/web/index.php:189:array(1) { 'rueckgabe' => array(0) { }}

Es ist auch nichts dazwischen, wo die Variable gefüllt werden könnte. Darüber hinaus wird sie, wenn gefüllt und ausgegeben, direkt per unset gelöscht
 
Zuletzt bearbeitet:
Also ich seh spontan nix, gibter dir bei der Fehlernummer ne Zeilennummer und ist das die mit $_SESSION["rueckgabe"][] = "<p>Fehler bei.... oder ist das nur geraten dass es das sein muss?
 
mischaef schrieb:
Darüber hinaus wird sie, wenn gefüllt und ausgegeben, direkt per unset gelöscht
Hast Du vielleicht in einem Tab etwas gemacht, was sie löscht, während sie in einem anderen Tab beim anschließenden Request noch benötigt wurden, aber dann halt nicht mehr da waren?
 
@Guyinkognito
Es wurde mir als Fehlermeldung die Zeile angegeben, in der der Text in die Session geschrieben werden sollte.

@H4110
Nein, bei der Datei kam nichts per include oder so rein, falls Du das meinst.

Der Gedanke, der mit jetzt dabei kommt: Wie ist das denn, wenn der Teil der Session bereits mit einem String gefüllt war (obwohl ich im Code nichts dazu gefunden habe), dann könnte die Session doch nicht mehr in ein array gewandelt werden, oder?

Oder gibt es eine Möglichkeit, den Teil der Session zwar als array zu deklarieren, diesen aber dann so zu füllen, dass er zu einer normalen Variable wird und dann nicht mehr als Feld genutzt werden kann?

Ich versuche nur das Problem dahinter zu verstehen und das ganze daher ein wenig eingrenzen zu können.
 
Grundsätzlich sei gesagt, dass du die Session missbrauchst.
 
  • Gefällt mir
Reaktionen: Guru-Meditation, floq0r und H4110
Wieso das? In den Büchern, die ich über PHP gelesen habe, wurden sie, neben Loggin ect. genau dafür gebraucht. Wo liegt der Unterschied dabei zwischen ein paar für die Weiterverarbeitung gespeicherten Daten zu einem Warenkorb?
 
Fehlermeldungen* zB gehören nicht in die Session. Auch keine aktuellen Arbeitsdaten (also grob alles was in $_POST steht) und schon mal gar nicht HTML Code.

*Ein Fehler ist ein Fehler in eben diesem einen Request, aber nicht persistent in der Session. Ein Fehler über mehrere Requests ist eher ein Bug.

mischaef schrieb:
In den Büchern, die ich über PHP gelesen habe,
Ich rate sowieso von Büchern über spezielle Sprachen ab! Bücher über Meta wie Design Pattern, Architektur etc. ja. Aber spezielle Sprachen sind schwierig, zB ist PHP 5.x was ganz anderes als PHP 8.x. Allein was da alles deprecated ist, oder komplett removed. Was ich meine: spare dir das Geld für Bücher zu Sprache X. Kaufe dir Meta Bücher. Und google/rtfm die aktuelle Sprache (Sprachversion).
 
Zuletzt bearbeitet:
Validierung macht man eigentlich immer innerhalb eines Requests. Das Formular kommt per POST und wenn es fehlerfrei ist, speichert man es in der Datenbank. Wenn nicht, schickt man es mit Fehlermeldungen zur Weiterbearbeitung zurück.

Wenn man irgendwas in der Session speichert, muss man Nebenläufigkeit bedenken. D.h. in Deinem Fall, dass, wenn man das gleiche Formular in mehr als einem Tab offen hat, es keine Konflikte geben darf, weil sie dieselben Variablen verwenden.

Auch, wenn es sehr unwahrscheinlich ist: wenn das Formular in zwei Tabs gleichzeitig gepostet wird, hängen die möglicherweise abwechselnd ihre Felder an das jeweilige Array für das Feld dran, so dass die lustig durchgemischt werden. Was an sich auch so ein typischer Anfängerfehler ist: wenn, dann ein Array von Formular-Objekten, aber nicht x Arrays für jedes einzelne Feld. Dann würde bei gleichzeitigem Request und nicht-atomaren Update des Arrays schlimmstenfalls ein Formular verloren gehen.
Ergänzung ()

Server-seitig den Status für einen bestimmten Workflow zu speichern und dabei die Verwendung mehrerer Tabs zu berücksichtigen, ist allgemein ein ziemliches Problem. Elster z.B. unterbindet das: wenn man da mehr als einen Tab hat, wird man immer wieder zum Status des aktuellsten Tabs zurückgeworfen.
Ergänzung ()

Bei Jakarta EE (ehemals Java EE) gibt es dafür übrigens @ConversationScoped, habe ich aber noch nie verwendet.
 
Zuletzt bearbeitet:
H4110 schrieb:
Validierung macht man eigentlich immer innerhalb eines Requests.

Er validiert doch gar nicht oder siehst du da etwas? er schreibt die POST vars direkt in Session arrays...sehe auch keine Abfrage ob eine session array bereits existiert und/oder leer ist..nix...ausser 6 Zeilen Code der uns was zu seinem Problem sagen soll..

mischaef schrieb:
..ich habe ein PHP-Script

Dann zeig uns doch das ganze Script..
 
Jeder Session Zugriff (auf das Superglobal $_SESSION) ist ein schreibender Zugriff auf das Filesystem/DB.
Man sollte vermeiden in einer Schleife darauf zuzugreifen. Geht ja, geht aber auch besser.

Du kannst ein Array mit den Fehlermeldungen füllen in einer Schleife und nach dem Durchlauf dieser Schleife, das Array in die Session schreiben -> besser!

Und ja, Fehlermeldungen gehören perse nicht in die Session, wozu auch? Diese werden als Payload zurück an den Client geschickt, welcher dann die Fehlermeldungen im/über dem Formular darstellt. Wozu brauche ich diese in der Session? Aber gut, kann ja durchaus ein valider Usecase sein.
 
  • Gefällt mir
Reaktionen: HoseeJonatan
[ChAoZ] schrieb:
Jeder Session Zugriff (auf das Superglobal $_SESSION) ist ein schreibender Zugriff auf das Filesystem/DB.
Die Session wird einmal zum Ende der Skript-Laufzeit geschrieben oder manuell mit session_write_close().

Wurde $_SESSION nicht verändert, wird die Datei auch nicht erneut geschrieben (session.lazy_write). Lediglich deren Timestamp wird aktualisiert, um Garbage Collection zu verhindern.

Es ist aber in jedem Fall empfehlenswert, nicht megabyteweise Daten in die Session schreiben; denn wird auch nur ein Byte verändert, serialisiert PHP die gesamte Session-Datei von Anfang bis Ende neu.
 
Zurück
Oben