Unterschiedliches Verhalten bei IE 7 und FF 3
detlevk
- php
Vorneweg:
Ich bin seit einiger Zeit dabei, mich allein in PHP einzuarbeiten und habe leider vor Ort niemanden den ich fragen kann. Das im folgenden beschriebene Problem bringt mich allerdings fast zur Verzweiflung, weil ich den Ansatz nicht finde!
Kurzbeschreibung des Projekts:
Es soll ein Shop mit PHP und MySQL erstellt werden. In diesem Shop gibt es einen Warenkorb. Dieser ist als temporäre Tabelle in der Datenbank unter dem Namen der Session abgelegt. Mit Abschluss des Bestellvorgangs werden die Daten umkopiert und die temporäre Tabelle gelöscht.
Der Warenkorb wird über Buttons von der Artikelseite aufgerufen:
Der jeweils angezeigte Artikel soll durch Klick auf das Symbol mit Pfeil in den Warenkorb hinzugefügt weren. Ein Klick auf das einfache Warenkorbsymbol zeigt den bisherigen Inhalt an ohne etwas zu verändern.
Die Ansicht des Warenkorbes soll nach Hinzufügen eines Artikels z.B. so aussehen:
Durch den grünen Button soll die Anzahl je Klick um 1 erhöht werden, der rote Button bewirkt Verminderung um 1. Das Mülltonnensymbol löscht den Artikel komplett aus dem Warenkorb. Der Button mit dem durchgestrichenen Warenkorbsymbol löscht den kompletten Warenkorb.
Problembeschreibung:
Im Internet Explorer 7 funktioniert alles wie gewünscht.
Im Firefox 3 treten diese Fehler auf:
Codeausschnitt der Artikelseite:
// Navigations-Buttons
echo "<p align=center>";
echo "<a href='index.html'><img alt='Start' src='Buttons/Start.gif' border=0></a>";
echo "<a href='Kontakt.html'><img alt='Bestellung' src='Buttons/Bestellung.gif' border=0></a>";
echo "<a href='AGB.html'><img alt='AGB' src='Buttons/AGB.gif' border=0></a>";
echo "<a href='show_cat_form.php?kategorie=$kat'>";
echo "<img alt='Übersicht' src='Buttons/Uebersicht.gif' border=0></a>";
echo "</p>";
Warenkorb:
Hier füge ich ausnahmsweise den Code des gesamten Skripts ein, weil mir nicht klar ist, was das merkwürdige Verhalten auslöst. Vertrauliche Daten (Datenbank-Anmeldung) wurden durch *** unkenntlich gemacht.
Die Variable $wert regelt die Änderungen im Warenkorb:
1 - Bestimmten Artikel hinzufügen bzw. Anzahl um 1 erhöhen
2 - Anzahl eines best. Artikels um 1 vermindern
3 - Einen bestimmten Artikel löschen
Code:
<?php
//Funktion: Artikelbestand abfragen
function bestand($artNr, $db)
{
$sql_art = "SELECT * FROM Artikel WHERE ArtNr = '$artNr'";
$art_result = mysql_query($sql_art, $db);
if ($art_result)
{
$artObject = mysql_fetch_object($art_result);
$bestand = $artObject->Bestand;
}
else
{
echo "<p>".mysql_error($db)."</p>";
}
return $bestand;
}
//Session starten
session_start();
$sessionid = session_id();
$kat = $_GET['kat']; //Kategorienummer der Übersicht
session_register("kat");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Warenkorb</title>
</head>
<body>
<p align=center><img alt='Logo' src='Logos/Logo_lang.gif'></p>
<?php
// Herstellung der Verbindung zur Datenbank
$db = @mysql_connect('reifrockmaus.de', '****', '****');
if ($db)
{
$dbase = "d006306b";
mysql_select_db($dbase, $db);
}
else
{
echo "<p><b>Fehler, keine Datenbankverbindung!</b></p>";
}
//Abfrage des übertragenen Artikels
if(isset($_GET['artikel']))
{
$sql_select_article = "SELECT * FROM Artikel WHERE ArtNr = '$artikel'";
$result_article = mysql_query($sql_select_article, $db);
if ($result_article)
{
$object = mysql_fetch_object($result_article);
$artNr = $object->ArtNr;
$artBez = $object->Bezeichnung;
$price = $object->Preis;
$number = $object->Anzahl;
$versD = $object->VersandD;
}
else
{
echo "<p>".mysql_error($db)."</p>";
}
//Erzeugung der zur Session gehörenden Datenbanktabelle
$sql_create_session = "CREATE TABLE IF NOT EXISTS $sessionid
(
id INTEGER NOT NULL AUTO_INCREMENT,
ArtNr CHAR(6),
ArtBez CHAR(60),
Preis FLOAT(5,2),
Anzahl INTEGER(3),
VersandD FLOAT(5,2),
PRIMARY KEY(id)
)";
$result_table = mysql_query($sql_create_session, $db) or die("Fehler beim Anlegen der Sessiondatei $sessionid");
if ($result_table) // Tabelle wurde angelegt / existiert
{
//Datensatz abfragen
$sql_item_inside = "SELECT * FROM $sessionid WHERE ArtNr = '$artNr'";
$inside = mysql_query($sql_item_inside, $db);
if ($inside)
{
$actObject = mysql_fetch_object($inside);
$actArtNr = $actObject->ArtNr;
$actArtBez = $actObject->ArtBez;
$actNumber = $actObject->Anzahl;
$wert = $_GET['wert'];
if ($wert == 1)
{
$bestand = bestand($actArtNr, $db);
if ($actNumber < $bestand)
{
$actNumber++;
}
else if ($bestand)
{
echo "<p align=center>Datensatz $artNr Bestand erschöpft!</p>";
}
}
else if ($wert == 2 && $actNumber > 1)
{
$actNumber--;
}
if ($actArtNr == $artNr && $wert < 3)
{
//Datensatz aktualisieren
$sql_update = "UPDATE $sessionid SET Anzahl=$actNumber WHERE ArtNr = '$artNr'";
$update = mysql_query($sql_update, $db);
if ($update)
{
echo "<p align=center>Datensatz $artNr aktualisiert!</p>";
}
else
{
echo "<p>".mysql_error($db)."</p>";
echo "<p>Datensatz konnte nicht aktualisiert werden!</p>";
}
}
else if ($wert < 3)
{
//Datensatz einfügen
$sql_insert_item = "INSERT INTO $sessionid VALUES (0, '$artNr', '$artBez', $price, 1, $versD)";
$insert = mysql_query($sql_insert_item, $db);
if ($insert)
{
echo "<p align=center>Datensatz $artNr eingefügt.</p>";
}
else
{
echo "<p>".mysql_error($db)."</p>";
echo "<p>Datensatz konnte nicht eingefügt werden!</p>";
}
}
else if ($wert == 3)
{
//Datensatz löschen
$sql_delete_item = "DELETE FROM $sessionid WHERE ArtNr ='$artNr'";
$delete = mysql_query($sql_delete_item, $db);
if ($delete)
{
echo "<p align=center>Datensatz $artNr gelöscht.</p>";
}
else
{
echo "<p>".mysql_error($db)."</p>";
echo "<p>Datensatz konnte nicht gelöscht werden!</p>";
}
}
}
else
{
echo "<p>".mysql_error($db)."</p>";
echo "<p>Datensatz konnte nicht abgefragt werden!</p>";
}
}
else
{
echo "<p>".mysql_error($db)."</p>";
}
}
else
{
echo "<p>".mysql_error($db)."</p>";
}
//Anzeige der bisherigen Artikel
$sql_select_session = "SELECT * FROM $sessionid";
$result_session = mysql_query($sql_select_session, $db);
if ($result_session)
{
echo "<h1 align=center>Ihr Warenkorb:</h1>";
echo "<table align=center><tr><th>Nr.</th><th>ArtNr</th><th>Bezeichnung</th>".
"<th>Anzahl</th><th>Preis</th><th>Gesamtpreis</th></tr>";
while ($object = mysql_fetch_object($result_session))
{
$myArtNr = $object->ArtNr;
echo "<td>".$object->id.
"</td><td>".$myArtNr.
"</td><td>".$object->ArtBez.
"</td><td>".$object->Anzahl.
"</td><td> € ".number_format($object->Preis,2,',','.').
"</td><td> € ".number_format($object->Anzahl * $object->Preis,2,',','.').
"</td><td><a href='{$_SERVER['PHP_SELF']}?artikel=$myArtNr&wert=1&kat=$kat'>".
"<img alt='plus' src='Buttons/greup.gif' border=0></td></a>".
"<td><a href='{$_SERVER['PHP_SELF']}?artikel=$myArtNr&wert=2&kat=$kat'>".
"<img alt='minus' src='Buttons/reddown.gif' border=0></td></a>".
"<td><a href='{$_SERVER['PHP_SELF']}?artikel=$myArtNr&wert=3&kat=$kat'>".
"<img alt='Artikel löschen' src='Buttons/Tonne.gif' border=0></td></a></tr>";
$sumItem = $sumItem+$object->Anzahl;
$sumPrice = $sumPrice+$object->Preis*$object->Anzahl;
}
//Summenzeile
echo "<tr><td></td><td></td><td>Gesamtsumme:</td><td>$sumItem</td><td></td><td> € ".
number_format($sumPrice,2,',','.')."</td></tr>";
echo "</table>";
}
else
{
echo "<h1 align=center>Ihr Warenkorb ist noch leer!</h1>";
}
echo "<p align=center>".
"<a href='show_cat_form.php?kategorie=$kat'>".
"<img alt='Übersicht' src='Buttons/Uebersicht.gif' border=0></a>".
"<a href='Maske.php?id=$sessionid'><img alt='Bestellung' src='Buttons/Bestellung.gif' border=0></a>".
"<a href='Loeschen.php?id=$sessionid'>".
"<img alt='Warenkorb löschen' src='Buttons/Warenkorb_loeschen.gif' border=0></a></p>";
?>
</body>
</html>
Mir ist klar, dass wohl noch weitere Fehler oder Stilungenauigkeiten im Code sein werden. Für Hinweise dafür bin ich auch immer dankbar. Wichtig ist für mich aber in erster Linie, dieses beschriebene Verhalten zu verstehen!
Vielleicht ist es ja nur eine Kleinigkeit, die ich in meiner Betriebsblindheit übersehen habe?
(...)
"</td><td> € ".number_format($object->Preis,2,',','.').
"</td><td> € ".number_format($object->Anzahl * $object->Preis,2,',','.').
"</td><td><a href='{$_SERVER['PHP_SELF']}?artikel=$myArtNr&wert=1&kat=$kat'>".
"<img alt='plus' src='Buttons/greup.gif' border=0></td></a>".
"<td><a href='{$_SERVER['PHP_SELF']}?artikel=$myArtNr&wert=2&kat=$kat'>".
"<img alt='minus' src='Buttons/reddown.gif' border=0></td></a>".
"<td><a href='{$_SERVER['PHP_SELF']}?artikel=$myArtNr&wert=3&kat=$kat'>".
"<img alt='Artikel löschen' src='Buttons/Tonne.gif' border=0></td></a></tr>";
(...)
Beachte folgende Struktur:
<td><a ...><img></td></a>
Bitte korrigiere diesen Code (schließe das a-tag innerhalb von td) und probiere es noch einmal.
Gruß, LX
Beachte folgende Struktur:
<td><a ...><img></td></a>
Bitte korrigiere diesen Code (schließe das a-tag innerhalb von td) und probiere es noch einmal.
Gruß, LX
Danke für den Tipp!
War aber wohl nur Kosmetik. Der Fehler besteht immer noch.
Viele Grüße
Detlev
Als nächstes würde ich ein Firefox-Plugin wie Live-HTTP-Headers oder firebug nehmen, um mir die Requests anzuschauen: sendet Firefox etwa 2 Requests ab? Gibt es eine Weiterleitung? Es ist unwahrscheinlich, dass der Fehler in der Datenbank nur bei einem von 2 verschiedenen Clients auftritt.
Gruß, LX
Als nächstes würde ich ein Firefox-Plugin wie Live-HTTP-Headers oder firebug nehmen, um mir die Requests anzuschauen: sendet Firefox etwa 2 Requests ab? Gibt es eine Weiterleitung? Es ist unwahrscheinlich, dass der Fehler in der Datenbank nur bei einem von 2 verschiedenen Clients auftritt.
Gruß, LX
Den Verdacht auf 2 Requests habe ich auch. Jetzt muss ich mich nur noch mit den empfohlenen Helferlein vertraut machen.
Was mir nur völlig unverständlich ist: Wie kann ein solcher Fehler plötzlich auftreten, wenn es doch vorher schon ordentlich funktioniert hat?
Was mir nur völlig unverständlich ist: Wie kann ein solcher Fehler plötzlich auftreten, wenn es doch vorher schon ordentlich funktioniert hat?
Der Firefox 3 schickt tatsächlich jeden Request doppelt ab!
Woran kann das liegen?
Das schöne ist: Bei einer komplett überarbeiteten Version mit einem Array innerhalb der Session tritt das auch auf!
echo $begrüßung;
Der Firefox 3 schickt tatsächlich jeden Request doppelt ab! Woran kann das liegen?
Die Frage musst du mit deinem Quelltext klären. Wirf zunächst alles raus, was für das Problem nicht erforderlich ist. Verweise zu Stylesheets, Bildern, Javascript, andere Ressourcen, die eingebunden werden. Ist der Fehler dann weg, füge nacheinander die Verweise wieder ein, bis der Fehler wieder auftritt. Den Übeltäter kannst du dann genauer betrachten.
echo "$verabschiedung $name";
echo $begrüßung;
Im Firefox 3 treten diese Fehler auf:
- Artikel werden immer doppelt hinzugefügt
- Klick auf den grünen Button erhöht um 2 statt um 1
Installier dir im FF die livehttpheaders-Extension und beobachte, welche Requests abgesetzt werden.
Was hast du bisher zur Fehlersuche unternommen? Hast du dir beispielsweise anzeigen lassen, wie die SQL-Statements letztlich aussehen, die du dir zusammenbaust? Sind alle Variableninhalte so wie vorgesehen?
//Session starten
session_start();
Kommentare sind gut, wenn sie erklären, was mit dem Code bezweckt wird. Dieser hier ist wenig hilfreich, denn das Starten der Session erkennt man am Aufruf der gleichnamigen Funktion. Kommentiere lieber das was man nicht sieht.
$kat = $_GET['kat']; //Kategorienummer der Übersicht
session_register("kat");
session_register() zu verwenden ist schon seit Jahren nicht mehr nötig. Nimm das Array $_SESSION und schreib da deine Werte rein oder lies sie da aus. Dafür brauchst du keine Extra-Variable, denn du kannst direkt $_SESSION['beispiel'] dort verwenden wo du bisher die registrierte Variablen verwendet hast.
Was hat es für einen Hintergrund, dass du den Warenkorb in der Datenbank ablegst statt die Werte in der Session zu notieren bis die Bestellung perfekt gemacht werden kann? Dir bleiben Session-Tabellen-Leichen in der Datenbank zurück, wenn der Kunde die Bestellung nicht abschließt. Ist dir das bewusst?
echo "<p><b>Fehler, keine Datenbankverbindung!</b></p>";
"Und nun?" frage ich mich als Kunde. "Kann ich anderweitig meinen Bestellwunsch äußern oder soll ich gleich zur Konkurrenz gehen?"
echo "<p>".mysql_error($db)."</p>";
Die genaue Ursache geht den Kunden gar nichts an. Und wenn du nicht möchtest, dass jemand mit der Information Schaden anrichtet, gib sie ihm nicht. Besser ist es, Fehler zu loggen und dieses Log regelmäßig zu beobachten. (Im Fehlerfall eine Email an den Admin senden ist natürlich auch möglich.)
echo "<p align=center>Datensatz $artNr Bestand erschöpft!</p>";
echo "<p align=center>Datensatz $artNr aktualisiert!</p>";
echo "<p>".mysql_error($db)."</p>";
echo "<p>Datensatz konnte nicht aktualisiert werden!</p>";
echo "<p align=center>Datensatz $artNr eingefügt.</p>";
echo "<p>".mysql_error($db)."</p>";
echo "<p>Datensatz konnte nicht eingefügt werden!</p>";
usw. Sind das Informationen, die ein Kunde haben möchte? Schau nicht nur als Programmierer auf dein Werk sondern auch mal aus der Sicht der Anwender.
Ansonsten ist es schon gut, dass du dir über möglicherweise auftretende Fehler Gedanken gemacht hast. Viele Anfänger schreiben nur Schön-Wetter-Skripte.
number_format($sumPrice,2,',','.')."</td></tr>";
Ein paar Leerzeichen mehr erhöhen die Übersicht.
number_format($sumPrice, 2, ',', '.')
Dadurch werden die Parameter auch optisch voneinander abgegrenzt und erhöhen zumindest meine Geschwindigkeit beim Lesen des Codes.
Mir ist klar, dass wohl noch weitere Fehler oder Stilungenauigkeiten im Code sein werden. Für Hinweise dafür bin ich auch immer dankbar. Wichtig ist für mich aber in erster Linie, dieses beschriebene Verhalten zu verstehen!
Ich hab mehr zu diesen Fehlern etwas schreiben können. Das eigentliche Problem erschließt sich mir auch nicht direkt, aber mit Hilfe der oben genannten Werkzeuge hoffe ich, dass du etwas mehr zum Fehler findest. Wenn nicht, sehen wir weiter.
Du hast vermutlich üblicherweise dein Script klein angefangen und nun ist es gewachsen und wird langsam unübersichtlich, nicht zuletzt durch die Vermischung von verarbeitenden und ausgebenden Codeteilen. Wenn du Zeit für einen neuen Versuch hast, versuch dich mal mit dem EVA-Prinzip zu beschäftigen und die Daten verarbeitenden Teile von denen der Ausgabe zu trennen. Sammle zunächst alles was für die Ausgabe benötigt wird zusammen und erzeuge erst dann die Ausgabe. Auch das Thema kontextgerechte Behandlung von Werte solltest du nicht unberücksichtigt lassen.
echo "$verabschiedung $name";
echo $begrüßung;
»» Im Firefox 3 treten diese Fehler auf:
»» - Artikel werden immer doppelt hinzugefügt
»» - Klick auf den grünen Button erhöht um 2 statt um 1Installier dir im FF die livehttpheaders-Extension und beobachte, welche Requests abgesetzt werden.
Die Erweiterung wurde inzwischen installiert. Jetzt muss ich mich noch mit der Handhabung vertraut machen und werde dann weiter über die Ergabnisse berichten.
Was hast du bisher zur Fehlersuche unternommen? Hast du dir beispielsweise anzeigen lassen, wie die SQL-Statements letztlich aussehen, die du dir zusammenbaust? Sind alle Variableninhalte so wie vorgesehen?
Testausgaben diverser Variablen wurden gemacht.
»» //Session starten
»» session_start();
Kommentare sind gut, wenn sie erklären, was mit dem Code bezweckt wird. Dieser hier ist wenig hilfreich, denn das Starten der Session erkennt man am Aufruf der gleichnamigen Funktion. Kommentiere lieber das was man nicht sieht.
Schönheitsfehler, fliegt aber raus!
»» $kat = $_GET['kat']; //Kategorienummer der Übersicht
»» session_register("kat");session_register() zu verwenden ist schon seit Jahren nicht mehr nötig. Nimm das Array $_SESSION und schreib da deine Werte rein oder lies sie da aus. Dafür brauchst du keine Extra-Variable, denn du kannst direkt $_SESSION['beispiel'] dort verwenden wo du bisher die registrierte Variablen verwendet hast.
Wird auch noch geändert!
Was hat es für einen Hintergrund, dass du den Warenkorb in der Datenbank ablegst statt die Werte in der Session zu notieren bis die Bestellung perfekt gemacht werden kann? Dir bleiben Session-Tabellen-Leichen in der Datenbank zurück, wenn der Kunde die Bestellung nicht abschließt. Ist dir das bewusst?
Das Problem ist mir bewusst! Am Anfang der Entwicklung erschien mir dieser Ansatz besonders einfach und auch für einen Anfänger leicht umzusetzen. Nachträgliche Änderungen sind jetzt naturgemäß schwierig.
»» echo "<p><b>Fehler, keine Datenbankverbindung!</b></p>";
"Und nun?" frage ich mich als Kunde. "Kann ich anderweitig meinen Bestellwunsch äußern oder soll ich gleich zur Konkurrenz gehen?"
Diese und auch die meisten folgenden Ausgaben sind rein für Testzwecke und erscheinen selbstverständlich nicht in der endgültigen Version!
...
Ich hab mehr zu diesen Fehlern etwas schreiben können. Das eigentliche Problem erschließt sich mir auch nicht direkt, aber mit Hilfe der oben genannten Werkzeuge hoffe ich, dass du etwas mehr zum Fehler findest. Wenn nicht, sehen wir weiter.
Du hast vermutlich üblicherweise dein Script klein angefangen und nun ist es gewachsen und wird langsam unübersichtlich, nicht zuletzt durch die Vermischung von verarbeitenden und ausgebenden Codeteilen. Wenn du Zeit für einen neuen Versuch hast, versuch dich mal mit dem EVA-Prinzip zu beschäftigen und die Daten verarbeitenden Teile von denen der Ausgabe zu trennen. Sammle zunächst alles was für die Ausgabe benötigt wird zusammen und erzeuge erst dann die Ausgabe. Auch das Thema kontextgerechte Behandlung von Werte solltest du nicht unberücksichtigt lassen.
Da sehe ich mal wieder die Nachteile einer Hauruck-Entwicklung ohne Unterstützung von außen!
Nur: Woher soll ich den Goldesel für eine ordentliche Schulung nehmen?
Ich gabe aber die Hoffnung noch nicht auf und werde mich wieder hier melden, wenn die Untersuchung der Requests vielleicht neue Erkenntnisse gebracht hat.
mfg
Detlev
echo $begrüßung;
» Installier dir im FF die livehttpheaders-Extension und beobachte, welche Requests abgesetzt werden.
Die Erweiterung wurde inzwischen installiert. Jetzt muss ich mich noch mit der Handhabung vertraut machen und werde dann weiter über die Ergabnisse berichten.
Unter Extras "Live HTTP Headers" aufrufen und im anderen Tab einen zu untersuchenden Request erzeugen, sprich: auf den grünen Button drücken. Anschließend im Live-Tab nachsehen. Es kann sein, dass der Browser zwischendurch noch woanders hingeht, wenn er wegen Features wie dem Phishing-Filter mal eben nach Hause telefoniert. Diesen Request siehst du dann auch dort. Vielleicht ist es auch ein Zusammenspiel mehrerer Aktionen, so dass der grüne wirklich nur einmal erhöht, aber durch irgendeinen anderen Request die andere Erhöhung stattfindet.
echo "$verabschiedung $name";
Danke!
Bin jetzt gerade dabei, meine Testumgebung aufzuräumen und werde dann wohl noch so einiges durchzuprobieren haben!
mfg
Detlev