Problem beim Durchlaufen eines Array
Enrico
- php
Hallo und guten Abend,
ich habe ein Problem im Umgang mit einem Array.
Ich bekomme über $_POST Werte aus einem Formular geliefert, das ich dem Array $Artikel zuordne:
$Artikel = array ('Bezeichnung' => $Bezeichnung,
'Groesse' => $Groesse,
'Farbe' => $Farbe,
'Anzahl' => $Anzahl,
'Einzelpreis' => $Einzelpreis);
Nachfolgend will ich überprüfen, ob im Array $_SESSION['ID'] schon ein gleichnamiger Artikel abgelegt wurde.
Wenn ja, dann soll lediglich die Menge erhöht werden:
for ($i = 0; $i < count ($_SESSION['ID']); $i++)
{
----> if ($_SESSION['ID'][$i]['Bezeichnung'] == $Bezeichnung) <----
{
$_SESSION['ID'][$i]['Anzahl'] += 1;
}
else
{
$_SESSION['ID'][] = $Artikel;
}
}
In der markierten Zeile mit dem Abgleich bekomme ich aber folgende Fehlermeldung:
Fatal error: Cannot use string offset as an array
Muss ich das Session-Array tiefer "verschachteln" oder was habe ich hier falsch gemacht?
Danke für eure Hilfe und Gruß,
Enrico
Tach!
for ($i = 0; $i < count ($_SESSION['ID']); $i++)
foreach durchläuft ein Array, ohne dass man vorher zählen muss, wieviele Elemente es enthält. Und es können auch Lücken in den Keys enthalten sein.
----> if ($_SESSION['ID'][$i]['Bezeichnung'] == $Bezeichnung) <----
In der markierten Zeile mit dem Abgleich bekomme ich aber folgende Fehlermeldung:
Fatal error: Cannot use string offset as an array
Muss ich das Session-Array tiefer "verschachteln" oder was habe ich hier falsch gemacht?
Nicht raten, sondern erstmal genau nachsehen, was wirklich in dem Array steht: var_dump($_SESSION['ID'][$i]);
Und das error_reporting beim Entwickeln auf E_ALL sowie dislay_errors auf on stellen.
dedlfix.
Hallo,
ich denke, dass ich auf dem richtigen Weg bin.
Nach einigen fehlerhaften Versuchen habe ich jetzt das nachfolgende Skript erstellt:
<?PHP
session_start();
$ID = "bd57296a5fb28645ab49c303d7a7fee5";
$_SESSION['ID'] = array();
$_POST['Bezeichnung'] = "Artikel1";
$_POST['Anzahl'] = 2;
$_POST['Groesse'] = "M";
$_POST['Farbe'] = "Rot";
$_SESSION['ID']['Bezeichnung'] = array();
$_SESSION['ID']['Bezeichnung']['Anzahl'] = $_POST['Anzahl'];
$_SESSION['ID']['Bezeichnung']['Groesse'] = $_POST['Groesse'];
$_SESSION['ID']['Bezeichnung']['Farbe'] = $_POST['Farbe'];
foreach ($_SESSION['ID'] as $Schluessel => $Wert)
{
echo ("Key: " . $Schluessel . "<br/>\n");
echo ("Anzahl: " . $Wert['Anzahl'] . "<br/>\n");
echo ("Größe: " . $Wert['Groesse'] . "<br/>\n");
echo ("Farbe: " . $Wert['Farbe'] . "<br/>\n");
}
echo "<pre>";
var_dump ($_SESSION['ID']);
echo "</pre>";
?>
Es läuft fehlerfrei.
Die Festlegung der Variablen erfolgt hier nur zu Testzwecken.
Im Browser bekomme ich bei der foreach-Schleife folgende Anzeige:
Key: Bezeichnung
Anzahl: 2
Größe: M
Farbe: Rot
var_dump liefert mir folgende Übersicht:
array(1)
{
["Bezeichnung"] => array(3)
{
["Anzahl"] => int(2)
["Groesse"] => string(1) "M"
["Farbe"] => string(3) "Rot"
}
}
Aber irgendwie stehe ich noch gewaltig auf dem Schlauch oder habe einen Denkfehler, den ich nicht los werde.
Als ID soll eine zuvor erstelle, hier, wie oben bereits geschrieben, aber festgelegte ID übergeben werden, als eindeutiges Kennzeichen des Session-Array
Als Bezeichnung soll die hier festgelegte Bezeichnung "Artikel 1" das Array "einleiten" und jeweils eine eindeutige Bestellposition mit den weiteren Details Anzahl, Größe und Farbe kennzeichnen
Wie bekomme ich das noch umgesetzt?
Danke und Gruß,
Enrico
Tach!
$ID = "bd57296a5fb28645ab49c303d7a7fee5";
$_SESSION['ID'] = array();
Deine ID steckt nun in der Variable namens $ID. Als Schlüssel nimmst du aber das String-Literal 'ID'. Das heißt, dein Schlüssel lautet ID und die Variable wird nicht benutzt. Du kannst als Key auch die Variable notieren, dann wird ihr Inhalt als Schlüssel verwendet.
Als ID soll eine zuvor erstelle, hier, wie oben bereits geschrieben, aber festgelegte ID übergeben werden, als eindeutiges Kennzeichen des Session-Array
Warum eigentlich? Die Session-Daten liegen je nach Session getrennt herum. Über $_SESSION hast du nur auf die Daten der einen Session zugriff, aber nicht auf die der anderen. Die Verwendung einer weiteren ID, noch dazu eine aus einem festen Wert für die gesamte Anwendung, ergibt keinen Sinn.
Als Bezeichnung soll die hier festgelegte Bezeichnung "Artikel 1" das Array "einleiten" und jeweils eine eindeutige Bestellposition mit den weiteren Details Anzahl, Größe und Farbe kennzeichnen
Dann nimm den Variableninhalt - sprich: gib die Variable als Key an und kein String-Literal.
Glossar:
Ein String-Literal ist die Schreibweise, um einen String als Code auszudrücken. 'foo' und "bar" wären String-Literale in PHP.
dedlfix.
Hallo dedlfix,
Über $_SESSION hast du nur auf die Daten der einen Session zugriff
Da habe ich mich dann wohl falsch ausgedrückt.
Die ID wird über folgenden Code auf der Startseite erzeugt, da ich schon mehrfach gelesen habe, dass die IDs, die PHP erzeugt, nicht immer 100% sicher sein sollen:
$chars = md5 (uniqid (mt_rand(), true));
$ID = substr ($chars, 0, 8) . '-';
$ID .= substr ($chars, 8, 4) . '-';
$ID .= substr ($chars, 12, 4) . '-';
$ID .= substr ($chars, 16, 4) . '-';
$ID .= substr ($chars, 20, 12);
$_SESSION['ID'] = md5 (uniqid ($ID, true));
Mein Gedanke war dann folgender:
1. Erzeugung der ID und Festlegung der Session mit dieser ID als Einstiegselement
Du kannst als Key auch die Variable notieren, dann wird ihr Inhalt als Schlüssel verwendet
D.h. ich muss dann $_SESSION[$ID] statt $_SESSION['ID'] notieren?
2. Abgelegte Artikel mit deren Bezeichnung als Festlegung der nächsten Ebene
Letztendlich soll pro Besucher folgende Struktur erzeugt werden:
Besucher 1 hat sich eine Tunika ausgesucht:
$_SESSION[bd57296a5fb28645ab49c303d7a7fee5][Tunika]['Anzahl'] = 1
$_SESSION[bd57296a5fb28645ab49c303d7a7fee5][Tunika]['Groesse'] = "M"
$_SESSION[bd57296a5fb28645ab49c303d7a7fee5][Tunika]['Farbe'] = "Natur"
Besucher 2 hat sich einen Brillenhelm ausgesucht:
$_SESSION[56c28cf74ce8f33ba3a2cf8df537aef4][Brillenhelm]['Anzahl'] = 1
$_SESSION[56c28cf74ce8f33ba3a2cf8df537aef4][Brillenhelm]['Groesse'] = "L"
Gruß
Enrico
Tach!
Über $_SESSION hast du nur auf die Daten der einen Session zugriff
Da habe ich mich dann wohl falsch ausgedrückt.
Oder einen Denkfehler im Konzept - vielleicht auch zusätzlich.
Die ID wird über folgenden Code auf der Startseite erzeugt, da ich schon mehrfach gelesen habe, dass die IDs, die PHP erzeugt, nicht immer 100% sicher sein sollen:
Du bekommst mit keiner Methode eine 100%-Sicherheit hin. "Nicht sicher" bei einer Session-ID kann nur bedeuten, dass sie zu leicht erratbar ist. Ansonsten ist mit einer ausreichend hohen Anzahl an Versuchen jede ID erratbar. Es wird nur irgendwann unwirtschaftlich, sie durchzuprobieren. (Wobei man dabei nicht immer von der Maximalzahl an Möglichkeiten ausgehen muss, rein zufällig könnte man die ID ja auch schon beim ersten Versuch erraten, wenn das auch sehr unwahrscheinlich ist.)
Letztlich würde ich einfach auf PHP vertrauen. Dein Anwendungsfall ist anscheinend nur ein Shop und nicht Fort Knox. - Und glaub nur solchen Aussagen etwas, bei denen eine nachvollziehbare Begründung dabeisteht.
Mein Gedanke war dann folgender:
- Erzeugung der ID und Festlegung der Session mit dieser ID als Einstiegselement
Dann musst du diese ID auch als Session-ID verwenden und nicht innerhalb einer PHP-Session eine weitere ID hinzufügen. Schon ein simples foreach reicht aus, um deine in $_SESSION abgelegte ID zu finden - wenn dir jemand Code unterjubeln kann. Das bringt dir außer einer Verkomplizierung des Vorgangs keine Punkte.
Aber angenommen, du nimmst wirklich deine neue ID als PHP-Session-ID, dann hilft die gegen außenstehende Angreifer. Wer schon im System ist, kann sich auch über Dateizugriffe im session.save_path die Daten anschauen.
Du kannst als Key auch die Variable notieren, dann wird ihr Inhalt als Schlüssel verwendet
D.h. ich muss dann $_SESSION[$ID] statt $_SESSION['ID'] notieren?
Gemäß deines jetzigen Konzepts: ja.
- Abgelegte Artikel mit deren Bezeichnung als Festlegung der nächsten Ebene
Letztendlich soll pro Besucher folgende Struktur erzeugt werden:
Hier gilt daselbe Prinzip wie bei der ID.
dedlfix.
Hallo dedlfix,
danke Dir, dann sollte ich mein Vorhaben auch fehlerfrei umsetzen können.
Gruß
Enrico
Hallo dedlfix,
jetzt klappt mein Testcase:
$_SESSION[$ID] = array();
$Bezeichnung = "Artikel1";
$_POST['Anzahl'] = 2;
$_POST['Groesse'] = "M";
$_POST['Farbe'] = "Rot";
$_SESSION[$ID][$Bezeichnung] = array();
$_SESSION[$ID][$Bezeichnung]['Anzahl'] = $_POST['Anzahl'];
$_SESSION[$ID][$Bezeichnung]['Groesse'] = $_POST['Groesse'];
$_SESSION[$ID][$Bezeichnung]['Farbe'] = $_POST['Farbe'];
foreach ($_SESSION[$ID] as $Schluessel => $Wert)
{
echo ("Key: " . $Schluessel . "<br/>\n");
echo ("Anzahl: " . $Wert['Anzahl'] . "<br/>\n");
echo ("Größe: " . $Wert['Groesse'] . "<br/>\n");
echo ("Farbe: " . $Wert['Farbe'] . "<br/>\n");
}
liefert:
Key: Artikel1
Anzahl: 2
Größe: M
Farbe: Rot
array(1) {
["bd57296a5fb28645ab49c303d7a7fee5"]=>
array(1) {
["Artikel1"]=>
array(3) {
["Anzahl"]=>
int(2)
["Groesse"]=>
string(1) "M"
["Farbe"]=>
string(3) "Rot"
}
}
}
Gruß
Enrico