If-Anweisung wird verschluckt (ignoriert)

Alles, was PHP betrifft, kann hier besprochen werden.

If-Anweisung wird verschluckt (ignoriert)

Postby Poison of the Cursed » 22. January 2011 11:13

Hallo Zusammen,

seit meinem letzten Besuch konnte ich diverse Fehler in meinen Scripten (viele davon völlig unnötig, man wird schnell schludrig *schäm*) relativ gut oder mit der Suche über Google selbst lösen. Heute scheitere ich jedoch mal wieder an einer simplen if/else Anweisung und komme einfach nicht darauf, wo ich versehentlich einen Fehler eingebaut habe.

Meine Besucher melden sich an und wenn die angegebenen Daten mit den Benutzerdaten aus der Datenbank übereinstimmen, werden sie zum nächsten Step automatisch weitergeleitet. Die Weiterleitung musste ich einbauen, damit in der Navi-Leiste daneben der Link "Login" sofort durch den Link "Logout" ersetzt wird. Ohne Weiterleitung wechselt der Link ja erst, wenn eine andere Seite aufgerufen wird. Das aber nur am Rande zur Erklärung.

Hier nun der Code, der mir Probleme macht:
Code: Select all

if(isset($_GET["login"]) AND !empty($_GET["login"]))
{

$abfrage = "SELECT gutschrift FROM steckbrief WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$ergebnis = mysql_query($abfrage);
$row = mysql_fetch_object($ergebnis);

$eingeloggt = date("Y-m-d H:i:s");
$datum = date ("Y-m-d");


if($row->gutschrift < $datum)
{
$aendern = "UPDATE steckbrief Set eingeloggt='" . mysql_real_escape_string($eingeloggt) . "',
punkte=punkte+2, gutschrift='" . mysql_real_escape_string($datum) . "'
WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$update = mysql_query($aendern);

echo '<p>Hallo <b>'.htmlspecialchars($_SESSION['username']).'</b>, schön das Du da bist!<br>
Für Deinen heutigen Besuch werden Dir 2 Punkte gutgeschrieben.</p>
}
else
{
$aendern = "UPDATE steckbrief Set eingeloggt='" . mysql_real_escape_string($eingeloggt) . "'
WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$update = mysql_query($aendern);

echo '<p>Hallo <b>'.htmlspecialchars($_SESSION['username']).'</b>, schön das Du da bist!</p>
}

}


Die Spalte Gutschrift enthält ein Datum. Ist es kleiner als das Heutige, hat sich der Besucher heute noch nicht eingeloggt und erhält also 2 Punkte. Kommt er an einem Tag mehrmals auf die Seite soll er dann, wie im else-Teil beschrieben, nur noch begrüßt werden.

Problem:
Es ist mir jetzt schon öfter passiert, dass wenn ich mich das erste Mal am Tag einlogge (andere haben auch schon gemeckert), das Script die IF-Anweisung überspringt und gleich die ELSE-Anweisung ausgibt. Es also, trotz erstmaligen Einloggem am Tag keine Punkte gibt.
Seltsam auch: das ECHO aus der IF-Anweisung wird manchmal nur verschluckt. Was bedeutet, der Benutzer bekommt zwar nicht die Meldung, dass er die Punkte erhalten hat, aber sie sind ihm gut geschrieben worden.

Nun weiß ich nicht mehr weiter. Ich habe schon in Google nach einem solchen "Phänomen" gesucht, bin aber leider nur auf if/else-Probleme gestossen, bei denen der Code fehlerhaft war.
Liegt es vielleicht an der Weiterleitung? Die Anweisung selbst ist meiner Ansicht nach in Ordnung. Außer ich habe schon einen mega-mäßigen Knick in der Optik.
Oder muss ich vielleicht die Anweisungen, weil sie ineinander verschachtelt sind, anders aufteilen?

Bin für Hilfe und Anregungen sehr dankbar.

Liebe Grüße
Poison
Poison of the Cursed
 
Posts: 31
Joined: 27. April 2010 17:56

Re: If-Anweisung wird verschluckt (ignoriert)

Postby WilliL » 22. January 2011 11:40

aufgefallen:
<if>
echo '<p>Hallo <b>'.htmlspecialchars($_SESSION['username']).'</b>, schön das Du da bist!<br>
Für Deinen heutigen Besuch werden Dir 2 Punkte gutgeschrieben.</p>';

<else>
echo '<p>Hallo <b>'.htmlspecialchars($_SESSION['username']).'</b>, schön das Du da bist!</p>';

Bei eingeschaltetem error_reporting müsste das auffallen..
Willi
WilliL
 
Posts: 660
Joined: 08. January 2010 10:54
Operating System: Win7Home Prem 64 SP1

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Nobbie » 22. January 2011 11:44

Da kann man nichts mit anfangen, das ist ja nur ein Mini-Ausschnitt.

Es fragt sich sowieso, wie das funktionieren soll, wo steht denn diese Meldung "Hallo .... , schön dass Du da bist ...." usw. - da Du das mit echo ausgibst (statt irgendwie als Bestandteil einer kompletten Seite anzuzeigen), verstehe ich nicht, wo der Anwender diese Meldung sieht, ob er sie anschließend irgendwie wegklicken muss oder bestätigen oder wie? Wie funktioniert das?
Nobbie
 
Posts: 13170
Joined: 09. March 2008 13:04

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Nobbie » 22. January 2011 11:48

WilliL wrote:Bei eingeschaltetem error_reporting müsste das auffallen..


Nicht nur dann - das ist ein wüster Syntax Error mit Abbruch.
Nobbie
 
Posts: 13170
Joined: 09. March 2008 13:04

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Poison of the Cursed » 22. January 2011 13:13

Hallo Nobbie, hallo WilliL,

erstmal vielen Dank für die schnelle Rückmeldung. Ok, ich habe nur einen Ausschnitt mitgegeben, weil ich euch nicht komplett erschlagen wollte. Sorry mein Fehler.

Ok, hier mal das ganze Script der login.php:

Code: Select all
<?php
ob_start();
session_start();
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Club Potterverse</title>
<meta name="author" content="Regina Jost">
<meta name="copyright" content="Regina Jost">
<meta name="description" content="Auf Potterverse.de gibt es viel zu entdecken. Sieh' Dich um in der magischen Welt des Zauberschülers von Hogwarts, erkunde das Schloss und die Winkelgasse, nimm am Trimagischen Turnier teil, lege deine Prüfung im Apparieren ab, sammle Schokofrösche, löse Rätsel und gewinne Abzeichen.">
<meta name="keywords" content="Herr, der, Ringe, Schokofrösche, Vampire, Sammelkarten, Sammeln, Online, Tauschen, Zauberei, Magie">
<meta name="page-topic" content="Unterhaltung">
<meta name="page-type" content="Private Homepage ">
<meta name="audience" content="Fans, Kinder, Schüler, Jugendliche">
<meta name="robots" content="index, follow">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" type="text/css" href="/style.css">
<style>
.table { border: 3px double #cc6600; background-color: #ffcc66; }
.bghead { background-image: url(../club/bghead.gif); background-repeat:no-repeat; background-position: center;
width: 850px; height: 289px; }
.bgmiddle { background-image: url(../bg-pergament.gif); }
.bgfoot { background-image: url(../club/bgfoot.gif); background-repeat:no-repeat; background-position: center;
width: 850px; height: 57px; }
div#inhalt a:link,a:visited,a:active { font-weight: bold; color: #993300; text-decoration: none; }
div#inhalt a:hover { font-weight: bold; color: #cc6600; text-decoration: none; }
div#inhalt address { font-size: 12px; font-weight: bold; color: #993300; }
</style>
</head>

<body>

<div id="seite">

<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr><td colspan="2" class="bghead" valign="bottom">
<img src="../club/startseite.gif" alt=""></a>
</td></tr>
<tr class="bgmiddle"><td valign="top" width="180px" style="border-right: 1px solid #6e6047;">

<div id="info">
<?php
include("../menuclub.php");
?>
</div>

</td><td>

<div id="inhalt" align="center">

<script type="text/javascript">
function cursor() {
if (document.forms[0])
document.forms[0].elements[0].focus();
}
</script>
<body onLoad="cursor()"></body>

<?php
error_reporting(E_ALL);

$einloggen = '<form action="../club/login.php" method="post">
<table border="0" cellspacing="0" cellpadding="3" class="table">
<tr>
<td>Nickname:</td><td><input type="text" name="nickname" size="24" maxlength="50"></td>
</tr><tr>
<td>Passwort:</td><td><input type="password" name="passwort" size="24" maxlength="50"></td>
</tr><tr>
<td colspan="2" align="center"><input type="submit" name="gesendet" value="Einloggen"></td>
</tr></table></form>';


include("../connect.php");

if(!$verbindung OR !mysql_select_db("homepage"))
{
echo '<p>Dein LogIn ist leider fehlgeschlagen. Sollte dieser Fehler nochmals auftreten, sende
mir bitte eine E-Mail:
<br>
<br><a href="mailto:rjost@t-online.de">rjost@t-online.de</a></p>';
}
else
{



if(isset($_POST["gesendet"]) AND !empty($_POST["gesendet"]))
{

if(empty($_POST["passwort"]))
{
echo '<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Du hast vergessen Dein Passwort anzugeben.<br>

'.$einloggen.'</p>';
}
else if(empty($_POST["nickname"]))
{
echo '<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Du hast vergessen Deinen Nickname einzugeben.<br>

'.$einloggen.'</p>';
}
else
{



$abfrage = "SELECT nickname, passwort, aktiviert FROM registrierung
WHERE nickname='" . mysql_real_escape_string($_POST["nickname"]) . "'";
$ergebnis = mysql_query($abfrage);
$row = mysql_fetch_object($ergebnis);


$passwort = md5($_POST["passwort"]);


if(!isset($row->nickname) AND !isset($row->passwort))
{
echo '<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Tut mir leid,<br>
aber Du hast Dich noch nicht registriert.<br>

'.$einloggen.'</p>

<p>Hier geht es zur <a href="../club/anmeldung.php">Anmeldung</a>.</p>';
}
else if($row->aktiviert =="nein")
{
echo '<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Tut mir leid, aber Dein Account ist noch nicht aktiviert.<br>
Verwende den Link aus der Mail, die Du bei Deiner Registrierung erhalten hast,<br>
um Deinen Account zu aktivieren.

'.$einloggen.'</p>

<p>Hier geht es zur <a href="../club/anmeldung.php">Anmeldung</a>.</p>';
}
else
{


if($row->passwort != $passwort)
{
echo '<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Dein Passwort ist falsch.<br>

'.$einloggen.'</p>';
}
else
{

$_SESSION["username"] = $_POST["nickname"];

header("Location: ../club/login.php?login=1");

}
}
}
}



if(isset($_GET["login"]) AND !empty($_GET["login"]))
{

$abfrage = "SELECT COUNT(id) FROM nachrichten
WHERE an='" . mysql_real_escape_string($_SESSION["username"]) . "' AND status=0";
$ergebnis = mysql_query($abfrage);
$mengeid = mysql_fetch_row($ergebnis);
$mengeid = $mengeid[0];


if($mengeid == 0)
{
$nachrichten = 'Du hast keine neuen Nachrichten.';
}
else if($mengeid == 1)
{
$nachrichten = 'Du hast <b>1</b> neue Nachricht.';
}
else
{
$nachrichten = 'Du hast <b>'.$mengeid.'</b> neue Nachrichten.';
}


$abfrage = "SELECT gutschrift FROM steckbrief WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$ergebnis = mysql_query($abfrage);
$row = mysql_fetch_object($ergebnis);


$eingeloggt = date("Y-m-d H:i:s");
$datum = date ("Y-m-d");


if($row->gutschrift < $datum)
{
$aendern = "UPDATE steckbrief Set eingeloggt='" . mysql_real_escape_string($eingeloggt) . "',
punkte=punkte+2, gutschrift='" . mysql_real_escape_string($datum) . "'
WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$update = mysql_query($aendern);


echo '<p>Hallo <b>'.htmlspecialchars($_SESSION['username']).'</b>, schön das Du da bist!<br>
Für Deinen heutigen Besuch werden Dir 2 Punkte gutgeschrieben.<br>

<table border="0" cellspacing="4" cellpadding="5" width="75%" class="table">

<colgroup>
<col width="50%">
<col width="50%">
</colgroup>

<tr>
<td valign="top" style="border-bottom: 1px solid #cc6600;">
<a href="../club/steckbrief.php">Steckbrief</a><br>
<span style="font-size: 11px;">Hier kannst Du Deinen Punktestand<br>
ansehen und etwas über Dich<br>
verraten. :-)</span></td>
<td valign="top" style="border-bottom: 1px solid #cc6600;">
<a href="../club/nachrichten.php">Nachrichten</a><br>
<span style="font-size: 11px;">'.$nachrichten.'</span></td>
</tr><tr>
<td valign="top" style="border-bottom: 1px solid #cc6600;"><a href="../club/mitgliedersuche.php">Mitgliedersuche</a><br>
<span style="font-size: 11px;">Wenn Du Dir einen Überblick über<br>
die Mitglieder vom Potterverse-Club verschaffen möchtest oder<br>
jemanden suchst, bist Du hier richtig.</span></td>
<td valign="top" style="border-bottom: 1px solid #cc6600;"><a href="../club/sets.php">Kartensets</a><br>
<span style="font-size: 11px;">Geh doch einfach mal vorbei und schau Dich um, was es so gibt.</span></td>
</tr><tr>
<td colspan="2" valign="top"><a href="../club/logout.php">Ausloggen</a><br>
<span style="font-size: 11px;">Du wolltest heute nur Deine Punkte abholen?<br>
Ok, vielleicht bleibst Du das nächste mal länger.</span></td>
</tr></table></p>';
}
else
{
$aendern = "UPDATE steckbrief Set eingeloggt='" . mysql_real_escape_string($eingeloggt) . "'
WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$update = mysql_query($aendern);


echo '<p>Hallo <b>'.htmlspecialchars($_SESSION['username']).'</b>, schön das Du da bist!<br>

<table border="0" cellspacing="4" cellpadding="5" width="75%" class="table">

<colgroup>
<col width="50%">
<col width="50%">
</colgroup>

<tr>
<td valign="top" style="border-bottom: 1px solid #cc6600;">
<a href="../club/steckbrief.php">Steckbrief</a><br>
<span style="font-size: 11px;">Hier kannst Du Deinen Punktestand<br>
ansehen und etwas über Dich<br>
verraten. :-)</span></td>
<td valign="top" style="border-bottom: 1px solid #cc6600;">
<a href="../club/nachrichten.php">Nachrichten</a><br>
<span style="font-size: 11px;">'.$nachrichten.'</span></td>
</tr><tr>
<td valign="top" style="border-bottom: 1px solid #cc6600;">
<a href="../club/mitgliedersuche.php">Mitgliedersuche</a><br>
<span style="font-size: 11px;">Wenn Du Dir einen Überblick über<br>
die Mitglieder vom Potterverse-Club verschaffen möchtest oder<br>
jemanden suchst, bist Du hier richtig.</span></td>
<td valign="top" style="border-bottom: 1px solid #cc6600;">
<a href="../club/sets.php">Kartensets</a><br>
<span style="font-size: 11px;">Geh doch einfach mal vorbei und schau Dich um, was es so gibt.</span></td>
</tr><tr>
<td colspan="2" valign="top"><a href="../club/logout.php">Ausloggen</a><br>
<span style="font-size: 11px;">Du wolltest heute nur Deine Punkte abholen?<br>
Ok, vielleicht bleibst Du das nächste mal länger.</span></td>
</tr></table></p>';
}

}



if(!isset($_POST["gesendet"]) AND empty($_POST["gesendet"])
AND !isset($_GET["login"]) AND empty($_GET["login"]))
{
echo '<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Du hast Dich schon angemeldet und Deinen Account aktiviert?<br>
Schön, kannst Du Dich hier mit Deinem Nickname und Passwort einloggen.<br>

'.$einloggen.'</p>

<p>Falls nicht, musst Du zuerst zur <a href="../club/anmeldung.php">Anmeldung</a>.<br>
Solltest Du noch Fragen haben, schau doch einfach mal
<a href="../club/mitgliedschaft.php">hier</a> vorbei.<br>
<br>
Du hast Dein Passwort vergessen? Hier kannst Du Deine
<a href="../club/benutzerdaten.php">Benutzerdaten ändern</a>.</p>';
}


mysql_close ($verbindung);
}

ob_end_flush();
?>

<img src="../spacer.gif" alt="">

</div>

</td></tr>
<tr><td colspan="2" class="bgfoot"></td></tr></table>

</div>

</body>
</html>


Die Abfragen und die Auswertung der POST-Variablen erfolgt auf derselben Seite, auf der auch das Login-Formular zu finden ist. Also nur eine PHP-Datei für alles.

Auf meinem lokalen Server funktioniert das Script einwandfrei. error_reporting(E_ALL) ist wie ihr sehen könnt aktiviert. Fehlermeldungen erscheinen keine.

Ich habe nun (lokal) mindestens 20mal hintereinander das Datum aus der Spalte gutschrift (Tabelle Steckbrief) gelöscht und mich wieder neu eingeloggt. Jedesmal gibt er das ECHO aus dem IF-Teil der Anweisung ohne Probleme aus und schreibt die Punkte gut.

Das Script liegt seit 09.01.2011 auf dem Server von T-Online. Bis heute morgen habe ich jeden Tag schön die Meldung bekommen, dass ich für meinen heutigen Besuch 2 Punkte erhalte. Heute morgen hat er die Meldung verschluckt, mich nur begrüßt und die 2 Punkte dennoch gut geschrieben. Von anderen Besuchern habe ich in den letzten Tagen immer mal wieder eine Meldung bekommen, so ala "die letzten Tage ging alles einwandfrei, heute trat der Fehler wieder auf".
Dieser Fehler erfolgt also nur sporadisch, was ich nicht nachvollziehen kann.

Leider bekomme ich bei T-Online keinerlei Fehlermeldungen angezeigt, weil dieser Provider die Ausgabe eines error_reporting unterbindet. Bei einem richtigen Syntax-Fehler wird nur eine weiße Seite ohne irgendwelche Hinweise auf Probleme ausgegeben.

Wie gesagt, ich kann mir nicht erklären, warum es online fünf Tage am Stück gut läuft und dann plötzlich wieder nicht. Das einzige was mir dazu eingefallen ist, dass ich bei der Verschachtelung der Anweisungen vielleicht an einer Stelle was falsch gemacht habe und das Script darum immer mal wieder "hustet". Ich komme aber leider nicht drauf, wie ich es anders machen könnte.
Ach ja, was mir noch aufgefallen ist: die Seite "hüpft" manchmal seltsam. (Sorry, kann es nicht besser beschreiben.) Als würde ich noch während dem Aufbau der Seite auf "Auffrischen" drücken oder mitten im Script würde ein "refresh" ausgeführt. Habe ich bei der Weiterleitung was falsch gemacht?

Liebe Grüße
Poison
Poison of the Cursed
 
Posts: 31
Joined: 27. April 2010 17:56

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Nobbie » 22. January 2011 16:16

Poison of the Cursed wrote:Habe ich bei der Weiterleitung was falsch gemacht?


Gelinge ausgedrückt: JA. Aber nicht nur da.

Das ganze Script ist grauenhaft falsch programmiert- es tut mit Leid das so sagen zu müssen. Offensichtlich hat es das Script vorne und hinten nicht getan, weswegen Du wahrscheinlich das Output-Buffering eingeschaltet hast (ob_start()) - dadurch ist die grundsätzlich vollkommen falsche Programmierung nicht ganz so offensichtlich und in der Tat scheint das Script wenigstens auf dem lokalen PC, wo Client und Server identisch sind, halbwegs zu laufen.

In der echten Welt kann es nicht laufen. Es ist durch und durch falsch programmiert.

Erst einmal die einfachen Dinge, um überhaupt solche Scripts später noch einmal zu verstehen:

a) Code innerhalb von if-Anweisungen werden eingerückt, um einen "Tab" (das ist je nach Einstellung 4 oder 8 Leerstellen). Bei geschachelteten if-Anweisung ist entsprechend geschaltet weiter einrzurücken.

b) wenn eine if-Abfrage zu einem logischen Programm-Ende führt, macht man KEINEN else-Zweig auf, sondern schreibt in den if-Block am Ende "exit()" und beendet damit das Script (was ja auch logisch so gewünscht ist).

Und nun zum Thema ob_start() und header()-Weiterleitungen:

a) es ist Unsinn, ob_start() zu benutzen, um Fehlermeldungen zu unterdrücken (Was bei Dir aber der einzige Grund ist). Als erstes nimmst Du das heraus. Und tust es NIE WIEDER hinein, erst wenn das Script vollkommen fehlerfrei läuft, dann könntest Du das tun. Aber für Programmieranfänger empfehle ich das nicht, weil es ihnen noch mehr die Logik des Programmes verschleiert.

b) es ist ebenso Unsinn, mit der header()-Funkion eine "Weiterleitung" auf ein Script zu veranlassen, was auf dem gleichen Server liegt, oder gar auf sich selbst. Scripte, die man heranziehen will, werden mit include() eingebunden, niemals mit header(). Nimm auch das komplett heraus, auch das führt dazu, dass Du die Programmlogik nicht bzw. falsch verstehst. Wenn die header()-Funktion in dieser Weise aufgerufen wird, passiert viel mehr und etwas ganz anderes, als Du Dir unter einer "Weiterleitung" vorstellst. Das könnte ich jetzt genau erklären, aber zunächst brauch man das gar nicht zu verstehen, nimm es erst einmal heraus.

Du mußt Dir unbedingt im klaren darüber sein, wie die Kommunikation zwischen Client (Browser) und Server (Apache und PHP) stattfindet. Wenn Du im Browser eine URL eingibst, fordert dieser den entsprechenden Server auf, die gewünschte Seite zu senden. Das tut Apache und der Inhalt dieser Seite wird vom Browser angezeigt. Die Verbindung zwischen Browser und dem Server ist dann geschlossen, Du könntest sogar das LAN-Kabel aus der Wand oder aus dem Router ziehen (oder WLAN ausmachen), das macht alles gar nichts. Wenn Du im Browser nun einen Link anklickst, oder einen Button drückst, dann sendet Browser wieder eine Anfrage an einen Server, oft ist es der gleiche Server wie davor. Davon weiß dieser Server aber nichts, der hat das komplett vergessen, dass Du vor paar Minuten schon einmal etwas angefordert hast. Er schickt Dir wieder eine Seite (bzw. macht das vielleicht mit Hilfe von PHP, weil Du ein PHP Script angefordert hast) und wieder wird sofort die Verbindung geschlossen, der Server vergisst sofort wieder alles und Du siehst im Browser, was er Dir gesendet hat.

Diese Dinge wie Cookies und Sessionvariablen sind Hilfsmittel (die ich jetzt auch noch nicht erläutere), wie man sich mit Hilfe von PHP beispielsweise "merken" kann, ob dieser Client (Browser) schon mal diesen Server und diese Seite angefragt hat und man damit ggf. den Client "wiedererkennen" kann. Das kann Apache von sich auch nicht, der tut nur saudoof immer dasselbe und weiß von nichts. Und im Prinzip mußt Du auch so denken lernen: Dein PHP Script senden IMMER eine vollständige Seite und sonst nichts. Möglicherweise wird das gleiche PHP Script kurz darauf erneut vom gleichen Anwender aufgerufen, die Sessions und Cookies ermöglichen es Dir, dieses zu erkennen bzw. zu verwalten und darauf zu reagieren. Je nachdem kannst Du dann mit dem gleichen Script eine andere Seite senden - aber immer dran denken: eine ganze HTML-Seite senden und sonst nichts.

Ein guter Programmierstil ist es dabei, NICHT lauter echo-Kommandos in sein Script zu bauen, sondern beispeislweise vorgefertige HTML Seiten zu bauen, wo der ganze Seiteninhalt drin steht und an den Stellen, wo eine Meldung oder ein variabler Inhalt steht (Benutzername zum Beispiel), da schreibst Du in den HTML Code keine festen Wert, sondern PHP Code zur Ausgabe einer Variablen. Das könnte so aussehen:

Code: Select all
<html>
....
<body>
<p>Willkommen sehr geehrter <?php echo $name?>!</p>
....
</html>


Nun mußt Du im PHP Script die Variable $name mit dem gewünschten Wert versehen, machst Du auch sonst alles notwendige, was Du für die Verarbeitung brauchst, und ganz am Schluss machst Du einen

Code: Select all
include "datei.html"


und danach kommt nur noch der Abschluss des PHP Script durch "?>"

Da man oft verschiedene Seiten anzeigen will, die sich so stark unterscheiden, dass man das nicht mehr nur durch einfache Variablen in den Griff bekommt (eben genau wie bei Deinem Login), dann baut man verschiedene HTML Dateien, mit verschiedenen Namen, baut die Programmlogik so, dass man verschiedene Dinge prüft, und am Ende jeder Prüfung (if-Abfrage), die eine bestimmte Seite zur Ausgabe als Folge hat, macht man wieder den include (mit dem gewünschten Dateinamen) und dann direkt danach einen "exit()". Damit ist dieser Programmzweig abgeschlossen.

Gewöhne es Dir also auch ab, mit echo die HTML Ausgabe zu machen (nur im HTML Dokument, wo die Variablen ausgegeben werden, da sind sie erlaubt, aber nicht im eigentlich PHP Script), sondern gib stattdessen immer ganze HTML Seiten aus und beende sofort danach das PHP Script.

Wenn man ganz "fortgeschritten" programmiert (aber das braucht nicht unbedingt zu sein), dann wird man sogar die verschiedenen includes auf verschiedene Dateien nicht mehr benötigen, sondern auch den Dateinamen selbst in eine Variable stecken und dann wirklich nur noch ganz am Ende des PHP Scripts einen einzigen include machen, und zwar auf diesen Variablennamen:


Code: Select all
---
include $datei;
?>


Solche HTML Dateien, wo nur an einzelnen Stellen PHP Variablen auftauchen, nennt man übrigens "Template". Du wirst nun lernen, selbst mit solchen Templates zu arbeiten, anstatt mit echo einzelne Fragmente irgendwo hinzuschreiben, die irgendwo im Nirwana landen, weil ob_start() die Ausgabe unterdrückt...

Also, nimm das ernst, beherzige diese Dinge und versuche es ganz neu auf diese Weise. Du wirst Deinen eigenen Programmcode viel besser verstehen lernen als heute.

P.S.: Das bedeutet NATÜRLICH AUCH, dass Du den ganzen HTML Klumpatsch, der im Moment noch in Deinem login.php drin steh (quasi alles ab Zeile 4), auch aus dem login.php herausnimmst. Das hat dort nichts verloren. Das gehört in das (oder in die) Templates, die Du im Verlauf der login-Prüfungen anzeigen willst. In PHP Scripten sollte nur PHP drin stehen. In den Templates steht dagegen das ganze HTML und ein bißchen PHP, da wo man Variablen eingefügt hat.
Nobbie
 
Posts: 13170
Joined: 09. March 2008 13:04

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Poison of the Cursed » 22. January 2011 19:27

Hallo Nobbie,

danke für die Rückmeldung. OK, ich habe verstanden, dass meine Art zu programmieren offensichtlich das schlechteste ist, was es auf Erden gibt. Aber ehrlich gesagt, habe ich nicht so recht kapiert, wie ich es besser machen soll.

Verstanden habe ich folgendes:

extra login.html, Inhalt
Code: Select all
<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Du hast Dich schon angemeldet und Deinen Account aktiviert?<br>
Schön, kannst Du Dich hier mit Deinem Nickname und Passwort einloggen.<br>

<form action="../club/login.php" method="post">
<table border="0" cellspacing="0" cellpadding="3" class="table">
<tr>
<td>Nickname:</td><td><input type="text" name="nickname" size="24" maxlength="50"></td>
</tr><tr>
<td>Passwort:</td><td><input type="password" name="passwort" size="24" maxlength="50"></td>
</tr><tr>
<td colspan="2" align="center"><input type="submit" name="gesendet" value="Einloggen"></td>
</tr></table></form></p>

<p>Falls nicht, musst Du zuerst zur <a href="../club/anmeldung.php">Anmeldung</a>.<br>
Solltest Du noch Fragen haben, schau doch einfach mal
<a href="../club/mitgliedschaft.php">hier</a> vorbei.<br>
<br>
Du hast Dein Passwort vergessen? Hier kannst Du Deine
<a href="../club/benutzerdaten.php">Benutzerdaten ändern</a>.</p>


Formular liefert alles in eine separate login.php, Inhalt z.B.

Code: Select all
<?php
error_reporting(E_ALL);

include("../connect.php");

if(!$verbindung OR !mysql_select_db("homepage"))
{
include("../verbindungsfehler.html");
exit();
}


if(empty($_POST["passwort"]))
{
include("../passwort_vergessen.html");
exit();
}

if(empty($_POST["nickname"]))
{
include("../nickname_vergessen.html");
exit();
}


$abfrage = "SELECT nickname, passwort, aktiviert FROM registrierung
WHERE nickname='" . mysql_real_escape_string($_POST["nickname"]) . "'";
$ergebnis = mysql_query($abfrage);
$row = mysql_fetch_object($ergebnis);


$passwort = md5($_POST["passwort"]);


if(!isset($row->nickname) AND !isset($row->passwort))
{
include("../nicht_registriert.html");
exit();
}

if($row->aktiviert == "nein")
{
include("../nicht_aktiviert.html");
exit();
}



if($row->passwort != $passwort)
{
include("../passwort_falsch.html");
exit();
}

$_SESSION["username"] = $_POST["nickname"];

//usw.
?>


Was ich nicht verstanden habe:
Heißt das, in der PHP-Datei steht auch kein Doctype, kein head-Tag etc?

Wenn der If-Zweig zu einem Programmende führt, soll ich keinen else-Zweig aufmachen. Ich dachte immer, ich müsste genau sagen, was getan werden muss, wenn if nicht zutrifft. Also am obigen Beispiel, wenn das Passwort aus der Datenbank mit dem Passwort aus der Eingabe im Formular übereinstimmt, mache aus POST-User einen SESSIOn-user. Oder würdest Du dann hier folgendes machen:

Code: Select all
if($row->passwort != $passwort)
{
include("../passwort_falsch.html");
exit();
}

if($row->passwort == $passwort)
{
$_SESSION["username"] = $_POST["nickname"];

$abfrage = "SELECT COUNT(id) FROM nachrichten
WHERE an='" . mysql_real_escape_string($_SESSION["username"]) . "' AND status=0";
$ergebnis = mysql_query($abfrage);
$mengeid = mysql_fetch_row($ergebnis);
$mengeid = $mengeid[0];

if($mengeid == 0)
{
$nachrichten = 'Du hast keine neuen Nachrichten.';//in html später nur Variable einbinden
}
else if($mengeid == 1)
{
$nachrichten = 'Du hast <b>1</b> neue Nachricht.';//in html später nur Variable einbinden
}
else
{
$nachrichten = 'Du hast <b>'.$mengeid.'</b> neue Nachrichten.';//in html später nur Variable einbinden
}

$abfrage = "SELECT gutschrift FROM steckbrief WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$ergebnis = mysql_query($abfrage);
$row = mysql_fetch_object($ergebnis);


$eingeloggt = date("Y-m-d H:i:s");
$datum = date ("Y-m-d");


if($row->gutschrift < $datum)
{
$aendern = "UPDATE steckbrief Set eingeloggt='" . mysql_real_escape_string($eingeloggt) . "',
punkte=punkte+2, gutschrift='" . mysql_real_escape_string($datum) . "'
WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$update = mysql_query($aendern);

include("../hallo_2punkte.html"); // hier dann die $nachrichten einbinden
exit();
}


if($row->gutschrift >= $datum)
{
$aendern = "UPDATE steckbrief Set eingeloggt='" . mysql_real_escape_string($eingeloggt) . "'
WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'";
$update = mysql_query($aendern);

include("../hallo_keine2punkte.html"); // hier dann die $nachrichten einbinden
exit();
}

usw.
}


Dann habe ich noch weitere Fragen. Diese "Weiterleitung" hatte ich nur eingebaut, damit in der includierten menu.php links vom Inhalt der Link Login gleich durch den Link Logout ersetzt wird. Wie würdest Du das lösen? Selbst wenn ich folgendes mache:

menu.php/html
Code: Select all
<?php
if(!isset($_SESSION["username"]) OR !$_SESSION["username"])
{
include("../menu_login.html");
exit();
}


if(isset($_SESSION["username"]) AND !empty($_SESSION["username"]))
{
include("../menu_logout.html");
exit();
}
?>


Zeigt er nach dem Login in der Navigation so lange den Link Login an, bis sich der Besucher auf eine andere Seite bewegt oder z.B. auffrischen drückt. Wie kann ich es ohne "Weiterleitung" oder refresh hinkriegen, dass der Besucher im Inhalt angezeigt bekommt, dass er eingeloggt ist und in der Navigation auch sofort Logout erscheint?

Ach ja, bei einer anderen Frage im Forum von Selfhtml wurde ich ziemlich gerügt, weil ich in einem meiner Scripte ein exit() drin hatte. Wäre mega-schlechter stil, ein Script einfach abzubrechen.
Jetzt nichts gegen das was du mir geraten hast. Ich lerne gern dazu und bin auch bereit meine Art etwas zu tun zu überdenken und zu verändern, aber was ist denn nun guter Stil? Ich bin etwas frustriert.

Liebe Grüße
Poison

P.S. Mir ist gerade noch was eingefallen. Wie sollte bei diesem Beispiel das Script am Besten aussehen (ist nur ein Ausschnitt, von den if(in array)-Abfragen hat es auf dieser Seite bis jetzt 26, Tendez steigend):

Code: Select all

$abfrage = "SELECT sammeln FROM potter_sa WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'
ORDER BY sammeln";
$ergebnis = mysql_query($abfrage);
while($row = mysql_fetch_object($ergebnis))
{
$sammeln[] = $row->sammeln;
}

//Set Cedric
if(in_array("cedric1", $sammeln) OR in_array("cedric2", $sammeln) OR in_array("cedric3", $sammeln)
OR in_array("cedric4", $sammeln) OR in_array("cedric5", $sammeln) OR in_array("cedric6", $sammeln)
OR in_array("cedric7", $sammeln) OR in_array("cedric8", $sammeln) OR in_array("cedric9", $sammeln))
{

echo '<table border="0" cellspacing="0" cellpadding="2"><tr><td>';

if(in_array("cedric1", $sammeln))
{
echo '<img src="../potter/karten/cedric1.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("cedric2", $sammeln))
{
echo '<img src="../potter/karten/cedric2.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("cedric3", $sammeln))
{
echo '<img src="../potter/karten/cedric3.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td></tr><tr><td>";

if(in_array("cedric4", $sammeln))
{
echo '<img src="../potter/karten/cedric4.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("cedric5", $sammeln))
{
echo '<img src="../potter/karten/cedric5.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("cedric6", $sammeln))
{
echo '<img src="../potter/karten/cedric6.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td></tr><tr><td>";

if(in_array("cedric7", $sammeln))
{
echo '<img src="../potter/karten/cedric7.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("cedric8", $sammeln))
{
echo '<img src="../potter/karten/cedric8.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("cedric9", $sammeln))
{
echo '<img src="../potter/karten/cedric9.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td></tr></table><br><br>";

}
else
{
echo "";
}

?>


Hierbei handelt es sich um ein Set mit Bildkarten. Wenn in der Variable $sammeln eine der Karten Cedric1-9 beinhaltet ist, sollte eine Tabelle mit 9 Feldern geöffnet werden. In dieser werden dann die Karten angezeigt, die im Array vorhanden sind. In den "leeren" Feldern wird ein Hintergrundbild angezeigt.
Poison of the Cursed
 
Posts: 31
Joined: 27. April 2010 17:56

Re: If-Anweisung wird verschluckt (ignoriert)

Postby WilliL » 22. January 2011 23:32

hallo Poison of the Cursed,
Heißt das, in der PHP-Datei steht auch kein Doctype, kein head-Tag etc?

Ich glaube das ist ein Missverständnis: Ausgabe immer eine ganze Seite

Nobbi hat mir mal vor einigen Monaten einen ähnlichen Tipp gegeben, den ich auch versucht habe umzusetzen.
Vielleicht noch nicht optimal aber vielleicht macht es das verständlicher..
BSP Ausgabeseite = Startseite
Code: Select all
<?php
// Pfad für XAMPP und HOSTER nach Bedarf definieren
If (($_SERVER["DOCUMENT_ROOT"] == "C:/xampp/htdocs") ? $rootpath = "C:/xampp/htdocs" : $rootpath = "/www/htdocs/HOSTER");
$inc_path = $rootpath."/scripts/";
/* ******* wichtig zum debuggen >>echo "<br> erg - ".mysql_errno(). ": " . mysql_error()."<br>"; ******* */

/*** einzubindende Dateien ***/
include_once ($inc_path."session.inc.php" );        // Charset = UTF-8, Erzwingen Session-Cookies, Session starten
include_once ($inc_path."common.inc.php" );         // serverabh. Parameter, error_reporting, Konstanten, DB, Crypt/Decrypt
// include_once ($inc_path."functions.inc.php");    // weitere nicht immer benötigte Funktionen
// include_once ($inc_path."validate.inc.php" );    // Validierungsroutinen
// include_once ($inc_path."login_func.inc.php" );  // Funktionen für den Login-Vorgang

/*  lokale Parameter für HTML, Zielfile für Submit im Formular */
$head_titel          = 'ss Mail';          // Anzeige Browser-TAB
$ueberschrift          = 'Out';            // Überschrift der Seite
$_SESSION['action_tag'] = "ss_mail.val.php";    // Zielfile für Submit im Formular
include_once ($inc_path."check_user.inc.php" );      // User-check, DB öffnen - immer für gesicherte Seite notwendig

   {     // Überprüfung der Rechte gergab JA, nur dann den HTML Teil ausgeben,
         // bei NEIN erfolgte vorher eine Umlenkung auf die Loginseite
      if (!isset($_SESSION['ss_mailsubject'])) $_SESSION['ss_mailsubject'] = '';
      if (!isset($_SESSION['ss_mailtext']))    $_SESSION['ss_mailtext']= '';
      
/*** -- Main -- ***/
      include_once ($inc_path."html_header.inc.php" );   // HTML-Kopf, Header, Navigation, Titel
      include_once ($inc_path."message.inc.php" );      // Meldungen ausgeben
      include_once ("ss_mail.form.php" );               // Mailformular anzeigen
      include_once ($inc_path."html_footer.inc.php" );   // HTML-Ausklang
/*** -- Main -- ***/
   } // ende 'Rechte: JA'
?>

Der Ablauf besteht bei mir aus 3 Teilen: Ausgabe (+Eingabe,Fehlerausgabe), Validierung, Datenbankupdate
Diese binden dann benötigte Module ein.

Da nur die Ausgabeseite etwas an den Browser schickt, sind auch nur hier die html tags notwendig. Die anderen Dateien sind "nur" funktionelle Scripts.
Willi
WilliL
 
Posts: 660
Joined: 08. January 2010 10:54
Operating System: Win7Home Prem 64 SP1

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Poison of the Cursed » 23. January 2011 07:20

Hallo WilliL,

vielen Dank für das Beispiel. Es ist nun schon etwas verständlicher. Allerdings muss ich sagen, dass ich nicht weiß, wie ich diese Art zu programmieren auf mein Script umsetzen soll.
Ok, ich habe mal versucht, die einzelnen Teile auseinanderzufieseln.

include_once ($inc_path."session.inc.php" ); // Charset = UTF-8, Erzwingen Session-Cookies, Session starten


Da ich keine Cookies verwende und mein Charset-UTF-8 nur im head-Tag habe, würde ich in den Teil folgendes packen:

Code: Select all
<?php
session_start();
?>


// include_once ($inc_path."login_func.inc.php" ); // Funktionen für den Login-Vorgang


Meiner Meinung nach das hier:

Code: Select all
<?php
error_reporting(E_ALL);

if(empty($_POST["passwort"]))
{
include("../passwort_vergessen.html");
exit;
}

if(empty($_POST["nickname"]))
{
include("../nickname_vergessen.html");
exit;
}


$abfrage = "SELECT nickname, passwort, aktiviert FROM registrierung
WHERE nickname='" . mysql_real_escape_string($_POST["nickname"]) . "'";
$ergebnis = mysql_query($abfrage);
$row = mysql_fetch_object($ergebnis);


$passwort = md5($_POST["passwort"]);


if(!isset($row->nickname) AND !isset($row->passwort))
{
include("../nicht_registriert.html");
exit;
}

if($row->aktiviert == "nein")
{
include("../nicht_aktiviert.html");
exit;
}


if($row->passwort != $passwort)
{
include("../passwort_falsch.html");
exit;
}

$_SESSION["username"] = $_POST["nickname"];

//usw.
?>


include_once ($inc_path."check_user.inc.php" ); // User-check, DB öffnen - immer für gesicherte Seite notwendig


Hier würde ich den Inhalt meiner jetzigen connect.php packen, also das hier:

Code: Select all
$verbindung = mysql_connect('localhost', 'Vesta', 'vesta');
mysql_select_db("homepage");

mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER SET 'utf8'");


include_once ($inc_path."html_header.inc.php" ); // HTML-Kopf, Header, Navigation, Titel


Das hier:

Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Club Potterverse</title>
<meta name="author" content="Regina Jost">
<meta name="copyright" content="Regina Jost">
<meta name="description" content="Auf Potterverse.de gibt es viel zu entdecken. Sieh' Dich um in der magischen Welt des Zauberschülers von Hogwarts, erkunde das Schloss und die Winkelgasse, nimm am Trimagischen Turnier teil, lege deine Prüfung im Apparieren ab, sammle Schokofrösche, löse Rätsel und gewinne Abzeichen.">
<meta name="keywords" content="Herr, der, Ringe, Schokofrösche, Vampire, Sammelkarten, Sammeln, Online, Tauschen, Zauberei, Magie">
<meta name="page-topic" content="Unterhaltung">
<meta name="page-type" content="Private Homepage ">
<meta name="audience" content="Fans, Kinder, Schüler, Jugendliche">
<meta name="robots" content="index, follow">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" type="text/css" href="../club/club.css">
<style>
.table { border: 3px double #cc6600; background-color: #ffcc66; }
.bghead { background-image: url(../club/bghead.gif); background-repeat:no-repeat; background-position: center;
width: 850px; height: 289px; }
.bgmiddle { background-image: url(../bg-pergament.gif); }
.bgfoot { background-image: url(../club/bgfoot.gif); background-repeat:no-repeat; background-position: center;
width: 850px; height: 57px; }
div#inhalt a:link,a:visited,a:active { font-weight: bold; color: #993300; text-decoration: none; }
div#inhalt a:hover { font-weight: bold; color: #cc6600; text-decoration: none; }
div#inhalt address { font-size: 12px; font-weight: bold; color: #993300; }
</style>
</head>

<body>

<div id="seite">

<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr><td colspan="2" class="bghead" valign="bottom">
<img src="../club/startseite.gif" alt=""></a>
</td></tr>
<tr class="bgmiddle"><td valign="top" width="180px" style="border-right: 1px solid #6e6047;">

<div id="info">
<?php
include("../menuclub.php");
?>
</div>

</td><td>

<div id="inhalt" align="center">


include_once ("ss_mail.form.php" ); // Mailformular anzeigen


Diesen Teil:

Code: Select all
<h2>LogIn</h2>
<img src="../club/login.gif" alt="">

<p>Du hast Dich schon angemeldet und Deinen Account aktiviert?<br>
Schön, kannst Du Dich hier mit Deinem Nickname und Passwort einloggen.<br>

<form action="../club/login.php" method="post">
<table border="0" cellspacing="0" cellpadding="3" class="table">
<tr>
<td>Nickname:</td><td><input type="text" name="nickname" size="24" maxlength="50"></td>
</tr><tr>
<td>Passwort:</td><td><input type="password" name="passwort" size="24" maxlength="50"></td>
</tr><tr>
<td colspan="2" align="center"><input type="submit" name="gesendet" value="Einloggen"></td>
</tr></table></form></p>

<p>Falls nicht, musst Du zuerst zur <a href="../club/anmeldung.php">Anmeldung</a>.<br>
Solltest Du noch Fragen haben, schau doch einfach mal
<a href="../club/mitgliedschaft.php">hier</a> vorbei.<br>
<br>
Du hast Dein Passwort vergessen? Hier kannst Du Deine
<a href="../club/benutzerdaten.php">Benutzerdaten ändern</a>.</p>


include_once ($inc_path."html_footer.inc.php" ); // HTML-Ausklang


Also, das hier:

Code: Select all
<img src="../spacer.gif" alt="">

</div>

</td></tr>
<tr><td colspan="2" class="bgfoot"></td></tr></table>

</div>

</body>
</html>


Was verbirgt sich, bei dir hinter?

include_once ($inc_path."message.inc.php" ); // Meldungen ausgeben


Was genau steht in deinem Formular bei form action="..."? Hast Du da dann die $_SESSION['action_tag'] statt einer URL eingebunden?

Sorry, wenn ich dich jetzt mit Einzelheiten nerve, ich versuche den Aufbau deines Script besser zu verstehen. Vielleicht kann ich es dann in meinen Seiten umsetzen.

Liebe Grüße
Poison
Poison of the Cursed
 
Posts: 31
Joined: 27. April 2010 17:56

Re: If-Anweisung wird verschluckt (ignoriert)

Postby WilliL » 23. January 2011 11:29

Ich hatte damals das ganze Script in für mich "logische" Abschnitte unterteilt und dabei dann die einzelnen Teilescripte über Include eingebunden.
So kann man nach und nach die einzelnen Funktionen nach und überarbeiten und optimieren

include_once ("ss_mail.form.php" ); // Mailformular anzeigen
Code: Select all
<?php
echo '      <form accept-charset="UTF-8" action="'.$_SESSION['action_tag'].'" method="post">
            <table>
               <tr>
                  <td><label for="mailsubject">';
                  if(isset($_SESSION['err_mail_sub']))  echo '<span style="color: #FF0000;">Betreff:</span>';
                  else          echo 'Betreff:';
echo'                  </label></td>
                  <td><input name="mailsubject" size=80 maxlength=60 value="'.$_SESSION['ss_mailsubject'].'" type="text"></td>
               </tr><tr>
                  <td><label for="mailtext">';
                  if(isset($_SESSION['err_mail_txt']))  echo '<span style="color: #FF0000;">Nachricht:</span>';
                  else          echo 'Nachricht:';
echo '                  </label><br>(500&nbsp;Zeichen)&nbsp;</td>
                  <td><textarea cols=80 rows=17 name="mailtext">'.$_SESSION['ss_mailtext'].'</textarea></td>
               </tr><tr>
               <tr><td></td></tr>';
echo '                <td>&nbsp;</td>
                   <td>   <input name="submit_j" type="submit" value="  senden  ">
                        <input name="submit_a" type="submit" value="  Abbruch ">
                   </td>';
echo            '</tr>
            <table>
         </form> ';
?>


wird immer benutzt include_once ($inc_path."message.inc.php" ); // Meldungen ausgeben
Code: Select all
<?php
$p2_tag = '</p></span>';
if(isset($_SESSION['ss_errtext'])){
   $p1_tag = '<span style="color: #FF0000"><p>';
   echo $p1_tag.$_SESSION['ss_errtext'].$p2_tag;
   unset($_SESSION['ss_errtext']);
} else if(isset($_SESSION['ss_infotext'])){
   $p1_tag = '<span style="color: #009944"><p>';
   echo $p1_tag.$_SESSION['ss_infotext'].$p2_tag;
   unset($_SESSION['ss_infotext']);
} else
   echo '<span style="color: #FFFFFF"><p>&nbsp;'.$p2_tag;
?>
Willi
WilliL
 
Posts: 660
Joined: 08. January 2010 10:54
Operating System: Win7Home Prem 64 SP1

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Poison of the Cursed » 23. January 2011 12:42

Hallo WilliL,

super, vielen Dank für die Info.
Ich habe jetzt schon mal angefangen und versucht das zu beherzigen, was Nobbie mir geraten hat.

Das Script für meine Startseite der Sammelkarten sieht jetzt so aus:

Code: Select all
<?php
include_once("../script/header.php"); // session_start, Abfrage SESSION-user, error_reporting
include_once("../potter/potter_head.html"); //html, head-tag bis zur div-inhalt
include("../connect.php"); // DB mit eventueller Fehlermeldung bei Nichterreichen

$kategorie = 'potter';
$kartensets = 'pottersets';
$karten_neu = 'potter_neu';
$startseite = 'potterstart';
$thema = 'Harry Potter';


if($_SESSION['pottermitglied'] == 0)  //diese Variable wird im Login-Script gesetzt
{
include_once("../meldung/freigeschalten.html");
exit;
}


if($_SESSION['pottermitglied'] == 1)
{
include_once("../script/start.php");
exit;
}


if(isset($_POST["freischalten"]) AND !empty($_POST["freischalten"]))  //sollte ich vielleicht kommplett auslagern?
{
include_once("../script/freischalten.php");
exit;
}

include_once("../potter/potter_foot.html");
?>


Alle HTML-Dateien enhalten nun, nur noch reinen HTML-Code in dem ab und zu eine Variable eingebettet ist. Die PHP-Dateien enthalten nur noch PHP, es ist nirgends mehr HTML dazwischen.

Sorry, habe nochmal ne Frage. Ich habe Seiten in denen ich aus der Datenbank verschiedene Daten in Schleifen ausgebe. Wäre das so erlaubt

abfrage.php (wird mit include_once) eingebunden
Code: Select all
<?php
$abfrage = "SELECT neu FROM ".$karten_neu." WHERE nickname='" . mysql_real_escape_string($_SESSION["username"]) . "'
ORDER BY neu";
$ergebnis = mysql_query($abfrage);
while($row = mysql_fetch_object($ergebnis))
{
$neu[] = $row->neu;
}

//hier sind alle Abfragen nacheinander drin
?>


ausgabe.html
Code: Select all
<p><a name="neu"><br></a><img src="../<?php echo ''.htmlspecialchars($kategorie).'';?>/neu.gif" alt=""><br><br>
<?php
foreach ($neu as $ausgabeneu)
{
echo '<img src="../<?php echo ''.htmlspecialchars($kategorie).'';?>/karten/'.htmlspecialchars($ausgabeneu).'.gif" alt="">&nbsp;';
}
?>

<form action="../<?php echo ''.htmlspecialchars($kategorie).'';?>/<?php echo ''.htmlspecialchars($verwaltenseite).'';?>.php" method="POST">
<select name="neu" size="1">';
<?php
foreach ($neu as $auswahlneu)
{
echo "<option value=$auswahlneu>$auswahlneu</option>";
}
?>
</select>
<select name="statusneu" size="1">
<option value="behalten">behalten</option>
<option value="sammeln">sammeln</option>
<option value="tauschen">tauschen</option></select>
<input type="submit" name="gesendetneu" value="OK">
</form></p>

//hier wird alles ausgegeben


oder sollte ich für die einzelnen Ausgaben der foreach-Schleifen statt ECHO besser eine html-Datei ausgeben in der als PHP-Code nur die $ausgabeneu eingebettet ist?
Dann wäre alles noch strikter getrennt. Wären dann halt für eine Seite ca. 14 Ausgabe-Dateien in html. Aber wie mir mein Freund sagte, ist die Anzahl der Dateien auf dem Server ist egal.

Probleme werde ich bei dieser strikten Trennung vermutlich nur mit dem Ausgabeteil bekommen:
Code: Select all
<?php
//Set Sirius
if(in_array("sirius1", $sammeln) OR in_array("sirius2", $sammeln) OR in_array("sirius3", $sammeln)
OR in_array("sirius4", $sammeln) OR in_array("sirius5", $sammeln) OR in_array("sirius6", $sammeln)
OR in_array("sirius7", $sammeln) OR in_array("sirius8", $sammeln) OR in_array("sirius9", $sammeln))
{

echo '<table border="0" cellspacing="0" cellpadding="2"><tr><td>';

if(in_array("sirius1", $sammeln))
{
echo '<img src="../potter/karten/sirius1.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("sirius2", $sammeln))
{
echo '<img src="../potter/karten/sirius2.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("sirius3", $sammeln))
{
echo '<img src="../potter/karten/sirius3.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td></tr><tr><td>";

if(in_array("sirius4", $sammeln))
{
echo '<img src="../potter/karten/sirius4.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("sirius5", $sammeln))
{
echo '<img src="../potter/karten/sirius5.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("sirius6", $sammeln))
{
echo '<img src="../potter/karten/sirius6.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td></tr><tr><td>";

if(in_array("sirius7", $sammeln))
{
echo '<img src="../potter/karten/sirius7.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("sirius8", $sammeln))
{
echo '<img src="../potter/karten/sirius8.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td><td>";

if(in_array("sirius9", $sammeln))
{
echo '<img src="../potter/karten/sirius9.gif" alt="">';
}
else
{
echo '<img src="../potter/karten/hintergrund.gif" alt="">';
}

echo "</td></tr></table><br><br>";

}
else
{
echo "";
}
?>


Vielleicht hast Du eine Idee, wie man das lösen könnte? Mir ist noch nichts eingefallen. Nun ja, eventuell finde ich noch etwas über Google.
Wünsche Dir noch einen schönen Tag.

Liebe Grüße
Poison

P.S. Noch eine Frage an Nobbie:
Auf meiner Seite können Besucher Sammelkarten in verschiedene Bereiche (Behalten, Tauschen, Sammeln...) verschieben. Das mache ich ebenfalls mit einem Formular. Nach dem Absenden wird die ausgewählte Karte aus einer Tabelle der Datenbank gelöscht und in eine andere Tabelle eingetragen. Klappt alles. Nur wenn jemand auf auffrischen drückt, wird ja die letzte Aktion nochmals ausgeführt. In diesem Fall würde die ausgwählte Karte zwar nicht mehr gelöscht, außer er hat nochmal eine dieser Art, aber sie wird ihm nochmal gut geschrieben. Wie kann ich das unterbinden? Das hatte ich auch mit einer "Weiterleitung" bzw. mit einem header, der auf einen Anker verweist, gemacht. Reicht da auch ein Exit?
Last edited by Poison of the Cursed on 23. January 2011 13:17, edited 1 time in total.
Poison of the Cursed
 
Posts: 31
Joined: 27. April 2010 17:56

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Altrea » 23. January 2011 13:12

Für Kontrollstrukturen in Template-Dateien gibt es eine alternative Syntax, die sehr hilfreich da übersichtlicher ist:

ungetestet:
Code: Select all
<?php foreach( $neu as $ausgabeneu ) : ?>
    <img src="../<?php echo htmlspecialchars( $kategorie ). '/karten/' .htmlspecialchars( $ausgabeneu ); ?>.gif" alt="">
<?php endforeach; ?>
We don't provide any support via personal channels like PM, email, Skype, TeamViewer!

It's like porn for programmers 8)
User avatar
Altrea
AF Moderator
 
Posts: 11926
Joined: 17. August 2009 13:05
XAMPP version: several
Operating System: Windows 11 Pro x64

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Nobbie » 23. January 2011 13:17

Poison of the Cursed wrote:Hallo Nobbie,

danke für die Rückmeldung. OK, ich habe verstanden, dass meine Art zu programmieren offensichtlich das schlechteste ist, was es auf Erden gibt.


Habe ich nicht gesagt, aber sie ist fehlerhaft (weswegen Du ja auch diese Probleme hast). Und ich denke das Grundproblem liegt darin begründet, dass Du die HTTP Abläufe nicht genau verstanden hast.

Die Programmierempfehlung, die ich Dir gegeben habe, ist nicht zwingend notwendig, aber es würde Dir auf Dauer die Arbeit sehr erleichtern (wenn Du es richtig anwendest). Dagegen ist es absolut zwingend notwendig, dass das Output-Bufferung abstellst - denn das benutzt Du asschließlich, um fehlerhafte Programmierung zu "kaschieren". Dadurch wird die Logik aber nicht richtig, sondern es treten nur weniger Fehlermeldungen auf. Dein Script MUSS auch ohne Output Bufferung vollkommen fehlerfrei arbeiten.

Poison of the Cursed wrote:Aber ehrlich gesagt, habe ich nicht so recht kapiert, wie ich es besser machen soll.


Im Grund gesehen musst Du nur lernen, dass Du seitenweise denkst, nicht zeilenweise. Wenn Du etwas ausgibst, immer die komplette HTML Seite und grundsätzlich ist diese Ausgabe auch die LETZTE Aktion im PHP Script. Wenn Du das konsequent befolgst, ist schon viel gewonnen. Ob Du das mit Templates realisierst oder einen gigantischen Riesen-Echo am Ende aufrufst oder eine Funktion baust, Du eine HTML Seite ausgibt - das musst Du selbst entscheiden. Aber Templates haben den gigantischen Vorteil, dass Du sie mit einem grafischen HTML Editor entwerfen kannst (du siehst also genau schon bei der Planung, die Seite aussehen wird) und an den entscheidenden Stellen fügst Du irgendwelche Platzhalter ein und ersetzt sie nachher in einem Texteditor durch PHP-Variablen (bzw. echo $variable).

Im Moment ist es ja, dass Du (außer einem konkreten Testlauf) gar keine Möglichkeit hast, Dir Deine gebauten Seiten anzuschauen, wie sie beim Anwender ankommen. Dazu mußt Du ja Dein PHP Script ausführen, das aber wiederum tut ja noch viel mehr als nur HTML ausgeben. Wäre es nicht super, wenn Du mit einem schönen WYSIWYG Editor die HTML Seiten entwerfen könntest und dann für Deine Ausgabe benutzen?

Poison of the Cursed wrote:Zeigt er nach dem Login in der Navigation so lange den Link Login an, bis sich der Besucher auf eine andere Seite bewegt oder z.B. auffrischen drückt.


Nein, das kann nicht sein. Es wird dieser Link angezeigt, weil Du den ausgibst. Wenn der Anwender sich einloggt (egal ob falsch oder sonstwas), bedeutet das wieder, dass Du eine Antwortseite sendest. Und Du hast die komplette Kontrolle darüber, wie diese Seite aussieht. Und wenn da ein Link steht mit dem "falschen Text" (Login oder so), dann hast Du das so an den Browser gesendet. Nichts ist dem Zufall überlassen. Von daher verstehe ich diesen Einwand nicht so ganz. Möglicherweise hast Du bereits im PHP Script diesen Link "hart verdrahtet". Nimm alles HTML aus dem Script heraus, natürlich auch die erste Zeile DOCTYPE. Dein PHP Script fängt mit <?php and endet am Schluss mit ?>. Das ist der Ideallfall. Und HTML steht (außer in Variablen und Strings) möglichst keines drin. Das gibst Du grundsätzlich durch include-Anweisung aus.

Poison of the Cursed wrote:Wie kann ich es ohne "Weiterleitung" oder refresh hinkriegen, dass der Besucher im Inhalt angezeigt bekommt, dass er eingeloggt ist und in der Navigation auch sofort Logout erscheint?


Indem Du ihm den dafür notwendigen HTML Code sendest. Oder arbeitest Du ggf. mit FRAMES und hast da irgendein Problem? Ich verstehe wirklich Dein Problem nicht - Du sendest dem Anwender doch grundsätzlich eine ganze Seite, immer (auch wenn Du es bisher ggf. unbewußt gemacht hast) und Du hast die vollkommene Kontrolle darüber, was darin steht. Und wenn es nur "Hello World" und sonst nichts - dann gibt es auch keine Navigation und nichts. Was bedeutet bei Dir "Navigation" und wie hast Du sie programmiert und wodurch wird sie ausgegeben?

Poison of the Cursed wrote:Ach ja, bei einer anderen Frage im Forum von Selfhtml wurde ich ziemlich gerügt, weil ich in einem meiner Scripte ein exit() drin hatte. Wäre mega-schlechter stil, ein Script einfach abzubrechen.


Da rennen mega-schlechte junge Script-Kiddies herum, die ein wenig Programmererfahrung gesammelt haben und einer schreibt die Dummheiten des anderen ab. Gib nichts um diesen Blödsinn und vertraue mir. Ich arbeite seit 1986 professionell in der IT Branche und habe viele Projekte und Kunden betreut und kenne selbstverständlich u.a. die Grundlagen der sog. "strukturierten Programmierung". Und ein exit() ist ganz normales, erlaubtes Konstrukt. Es KANN schlechter Programmierstil, wenn man es falsch einsetzt. Nämlich beispielsweise ohne vorher sämtliche Dateien zu schließen usw. - selbstverständlich soll das exit() nur der letzte ordentlich Abschluss sein, um die Programmausführung an diesem Punkt ordentlich zu beenden.

In Deinem Fall ist der exit() nahezu unvermeidbar, denn wenn Du ihn nicht benutzt, dann bist Du gezwungen, immer tiefer verschachtelte if-Anweisungen zu schreiben und im else-Zweig die Alternativverarbeitung fortzusetzen. Das ist wirklich schlechter Programmierstil, weil es nicht mehr lesbar ist. Logisch hört Dein Programm ja auf, wenn die erste if-Abfrage wahr ist. Dann ist ja Schluss (rein logisch). Aber bei Dir steht dann ein else dahinter, und darunter wieder Unterscheidung in x Fälle. Dadurch wird das immer weiter eingerückt und immer schlechter zu lesen, obwohl ja eigentlich jedesmal, wenn eine if-Abfrage erfüllt ist, das Script mit der Arbeit fertig ist. Wenn das so ist, dann kann man das auch so programmieren und schreibt eben "exit()" an das Ende der If-Anweisung. Dadurch braucht man keinen else-Zweig mehr aufzumachen, denn automatisch wird der Code, der nach dieser if-Abfrage steht, zum else-Fall, rein logisch gesehen. Dadurch braucht nicht tiefer zu verschachteln sondern kann normal weiter programmieren, nämlich das Verhalten, wenn die if-Abfrage NICHT erfüllt ist.

Poison of the Cursed wrote:Jetzt nichts gegen das was du mir geraten hast. Ich lerne gern dazu und bin auch bereit meine Art etwas zu tun zu überdenken und zu verändern, aber was ist denn nun guter Stil? Ich bin etwas frustriert.


Guter Stil ist weitestmögliche Trennung von Funktion und Präsentation. Sprich: nicht in einem einzigen PHP Script die Programmlogik UND die HTML Ausgabe (und dann auch noch kleckerweise via echo) zusammenzupacken, sondern die HTML Ausgabe so weit wie möglich aus dem PHP Code herausnehmen und in separate Dateien legen. Und abhängig von der Programmlogik wird diese oder jene Datei (Template) dem Anwender präsentiert. Die allermeisten Programmieranfänger programmieren so wie Du, packen alles in ein Riesenscript und vermanschen HTML Ausgabe mit Logik. Und das hat ja schon jede Menge Probleme bei Dir gegeben, Du kannst header() nicht benutzen, ohne ob_start() aufzurufen (deswegen hast Du es nämlich drin), weil schon HTML ausgegeben worden ist (was nicht sein darf, wenn man header() benutzen will) u.v.m.

Es ist mit völlig klar, dass Du jetzt erst einmal verstehen musst, was ich überhaupt meine und Du Deine lieben Probleme hast, das zu verstehen. Aber es ist dem HTTP Protokoll geschuldet, dass man auf eine bestimmte Weise programmiert, die der "Denkweise" dieses Protokolls entspricht.

Poison of the Cursed wrote:P.S. Mir ist gerade noch was eingefallen. Wie sollte bei diesem Beispiel das Script am Besten aussehen (ist nur ein Ausschnitt, von den if(in array)-Abfragen hat es auf dieser Seite bis jetzt 26, Tendez steigend):
...
Hierbei handelt es sich um ein Set mit Bildkarten. Wenn in der Variable $sammeln eine der Karten Cedric1-9 beinhaltet ist, sollte eine Tabelle mit 9 Feldern geöffnet werden. In dieser werden dann die Karten angezeigt, die im Array vorhanden sind. In den "leeren" Feldern wird ein Hintergrundbild angezeigt.


Da denke ich mir mal was aus, das kann man auch gut mit for-Schleifen programmieren, würde jetzt hier diesen Beitrag sprengen.
Nobbie
 
Posts: 13170
Joined: 09. March 2008 13:04

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Nobbie » 23. January 2011 13:39

[quote="Poison of the Cursed"]Das Script für meine Startseite der Sammelkarten sieht jetzt so aus:

Code: Select all
<?php
include_once("../script/header.php"); // session_start, Abfrage SESSION-user, error_reporting
include_once("../potter/potter_head.html"); //html, head-tag bis zur div-inhalt
include("../connect.php"); // DB mit eventueller Fehlermeldung bei Nichterreichen

$kategorie = 'potter';
$kartensets = 'pottersets';
$karten_neu = 'potter_neu';
$startseite = 'potterstart';
$thema = 'Harry Potter';


if($_SESSION['pottermitglied'] == 0)  //diese Variable wird im Login-Script gesetzt
{
include_once("../meldung/freigeschalten.html");
exit;
}


if($_SESSION['pottermitglied'] == 1)
{
include_once("../script/start.php");
exit;
}


if(isset($_POST["freischalten"]) AND !empty($_POST["freischalten"]))  //sollte ich vielleicht kommplett auslagern?
{
include_once("../script/freischalten.php");
exit;
}

include_once("../potter/potter_foot.html");
?>


Da will ich direkt eingreifen - so ist das falsch. So funktioniert das nicht. Wichtige Regel: HTML Ausgabe geschieht IMMER als allerletztes. Aber dagegen verstößt Du, weil Du bereits in der zweiten Zeile HTML includierst (und damit ausgbst):

Code: Select all
include_once("../potter/potter_head.html"); //html, head-tag bis zur div-inhalt


Das gehört dort nicht hin. Dadurch wird ja schon HTML ausgegeben, aber die Programmierlogik kommt ja erst dahinter. Es gibt zwei Möglichkeiten, dieses zu verbessern:

a) entweder Du machst Du den include immer zusammen mit dem include auf den eigentlich Inhalt, oder

b) Du lagerst diesen include aus in die einzelnen HTML Dateien und machst dort seinerseits am Anfang einen include auf den Header.

Auch die anderen includes sehen seltsam aus - mal includiest Du HTML Code (dann sollte es die letzte Aktion des Scripts sein), ein anderes Mal includierst Du aber ein PHP-Script "start.php". Wieso das? Du musst nicht die Programmierlogik auch komplett in include-Dateien auslagern. Das empfiehlt sich nur für Standardanweisung (beispielsweise wie die connect.php). Ansonsten schreibe in das Script hinein, was dort passieren soll, sonst erkennt man keine Programmlogik. Du kannst auch gerne eigene Funktionen dafür definieren und aufrufen, das ist viel verständlicher als Code zu includieren.

Was ich dort noch nicht verstehe, Du schreibst "if($_SESSION['pottermitglied'] == 0) //diese Variable wird im Login-Script gesetzt" - ist das hier nicht das Login-Script? Und was bedeutet diese Variable? Du darfst jetzt nicht den Fehler begehen, und Dein Script nur noch aus includes zusammenzubauen. Die Programmlogik geht dabei verloren, man kann nicht verstehen, was da passiert.
Nobbie
 
Posts: 13170
Joined: 09. March 2008 13:04

Re: If-Anweisung wird verschluckt (ignoriert)

Postby Altrea » 23. January 2011 13:41

Nobbie wrote:Dein PHP Script fängt mit <?php and endet am Schluss mit ?>. Das ist der Ideallfall.

Da möchte ich leise widersprechen. Das schließende ?> ist bei reinen PHP Dateien nicht notwendig und es hat keine Nachteile es wegzulassen.
Es wegzulassen hat allerdings den Vorteil, dass man damit unter Umständen das versehendliche senden von Leerzeichen verhindern kann, was dazu geführt hat, dass diese Empfehlung auch in diversen Coding Standards einzug erhalten und als best practice gilt.
We don't provide any support via personal channels like PM, email, Skype, TeamViewer!

It's like porn for programmers 8)
User avatar
Altrea
AF Moderator
 
Posts: 11926
Joined: 17. August 2009 13:05
XAMPP version: several
Operating System: Windows 11 Pro x64

Next

Return to PHP

Who is online

Users browsing this forum: No registered users and 14 guests