Session: Was ist hier los?
myrte
- php
Hallo.
Ich bin gerade dabei, ein Forum zu programmieren. Auf meinem Rechner (XAMPP für Windows) läuft alles Reibungslos, so wie ich es will. Doch dann hochgeladen, schon funktioniert es nicht mehr.
Auf meinem Rechener habe ich PHP 5.0.2, der Webspace hat PHP 4.x.x.
Das Problem liegt also an den Sessions.
Ich versuche es euch zu erklären:
Die ganze Sache basiert auf Sessions. Wenn sich ein Benutzer einloggt (auf der index.php), wird die session_id in eine Datei geschrieben. Dies alles macht die Datei login.php. Außerdem leitet sie dann wieder auf die index.php zurück. Jetzt aber mit "index.php?user=[NAME]". Hier wird jetzt geprüft, ob die aktuelle Session_id mit der in der Datei des Users übereinstimmt. Wenn ja, dann ist er logischerweise eingeloggt, es wird der Text "Du bist eingeloggt" angezeigt. Wenn nicht, dann wird ein Forumular angezeigt, mit dem man sich einloggen kann.
Hier ist schon mal der Quelltext der index.php. Ich habe die session_start() auskommentiert, weil PHP4 diese automatisch startet, während mein PHP5 dies nicht tut.
-------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Forum</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="pragma" content="no-cache">
<link rel="stylesheet" href="style.css">
<script type="text/javascript">
function fctpopup(){
F1 = window.open("new_forum.php","PopUp","width=700,height=500,top=50,left=50,resizable=no");
}
</script>
</head>
<!-- HHHHHHHHHHHHHHHHHHHHHHHHHHH -->
<body>
<?php // /*Session starten*/ session_start(); ?>
<div style="text-align:right; margin-right:20px; margin-top:10px;"><img src="titel.gif"></div>
<?php
// Wenn index.php?user=NAME, dann hole dem User seine session_id
$dh=@fopen("members/$user/session.ghi","r+");
// Wenn momentane session_id mit der in der Datei übereinstimmt, dann ist man eingeloggt. Bestätigung anzeigen
if(session_id() == @file_get_contents("members/$user/session.ghi")){
echo("<br>\n
<div style="text-align:right; width:100%; background-color:#CCCC99; left:0;">
<strong>Du bist eingeloggt</strong>
<div style="float:left; vertical-align:top;">
<form action="logout.php" method="get">
<input type="submit" value="Ausloggen">
</form>
</div>
</div>\n\n
");
}
else{
// Wenn die momentane session_id NICHT mit der in der Datei übereinstimmt, dann ist man nicht eingeloggt. Formular zum einloggen anzeigen
echo("
<div style="width:100%; text-align:right;">
<form action="login.php" method="get">
<div style="float:left;">Einloggen:</div>
Name: <input type="text" name="usr_name">
Passwort: <input type="password" name="usr_psw">
<input type="submit" value="Einloggen">
</form>
</div>\n\n
");
}
@fclose($dh);
// Öffne Ordner "cont", in dem die Einträge des Forums sind
$dh = opendir("cont");
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
array_shift($files);
array_shift($files);
echo "<br>\n";
// Jetzt alle vorhandenen Foren auflisten, in abwechselnder Farbe. Diese wird durch Wechseln der Variable $i gewährleistet
echo "<table border="0" cellpadding="0" cellspacing="0" bordercolor="#000000" class="overvw">\n";
$i=0;
foreach($files as $entry){
// Erste zwei Zeichen aus $entry entfernen
$new_entry = explode(" ",$entry);
array_shift($new_entry);
$entry=implode(" ",$new_entry);
// Tabelle in Abhängigkeit von Ordnern zeichnen
if($i==0){
echo "<tr>\n<td bgcolor="#00FFCC" width="70%"><a href="#">$entry</a></td>\n";
echo "<td bgcolor="#00FFCC" width="30%">Letzter Post</td>\n</tr>\n\n";
$i=1;
}
else{
echo "<tr>\n<td bgcolor="#CCFFCC" width="70%"><a href="#">$entry</a></td>\n";
echo "<td bgcolor="#CCFFCC" width="30%">Letzter Post</td>\n</tr>\n\n";
$i=0;
}
}
echo "</table>\n";
echo "<br>";
?>
<div class="div_new_topic"><br><a onclick="fctpopup()" href="">Neues Forum eröffnen</a></div>
<div class="div_bottom">- Registrieren - Wer ist registriert? - Wer ist gerade online? - Gehts auch ohne Registrierung? - Benutzereinstellungen - </div>
</body>
</html>
----------------------------------------------------------
Die login.php:
----------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>LogIn</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<?php // session_start() ?>
<?php
$usr_name=ucfirst($usr_name);
$usr_psw=md5($usr_psw);
$dh = opendir("members");
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
array_shift($files);
array_shift($files);
if(!(in_array($usr_name,$files))){
echo("<h3>Benutzer nicht registriert</h3>\nBitte versuche nicht, andere Benutzerkonten zu knacken, du wirst es nicht schaffen.<br><br>\n\n");
echo("<h4>Wenn du dich nur verschrieben hast, dann versuche es hier nochmals:<br>");
echo("
<form style="font-family:Arial, Helvetica, sans-serif; font-size:12px;" action="login.php" method="get">
Name: <input type="text" name="usr_name">
Passwort: <input type="password" name="usr_psw">
<input type="submit" value="Einloggen">
</form>
");
}
else{
$dh=fopen("members/$usr_name/pw.ghi","r+");
$usr_psw_rl=file_get_contents("members/$usr_name/pw.ghi");
/*
echo($usr_psw_rl);
echo("<br>");
echo($usr_psw);
*/
$dh2=fopen("members/$usr_name/session.ghi","r+");
if($usr_psw==$usr_psw_rl){
fwrite($dh2,session_id());
echo("<script type="text/javascript">self.location="index.php?user=$usr_name"</script>");
}
fclose($dh2);
fclose($dh);
}
?>
</body>
</html>
----------------------------------------------------------
Also. Das Problem ist, dass ich auf der hochgeladenen Seite (die auf dem Webspace) sofort eingeloggt bin. Unter meinem PHP5 muss ich erst den Namen und Passwort eintragen, um eingeloggt zu sein.
Entscheidend ist auch noch die Ordnerstruktur, nach dem dieses Forum geht:
-------------------------------------------------------------
Wo liegt hier der Fehler? Bin ich weider mal zu blond, so was zu machen?
Danke, eure myrte.
PS. : Seid bitte nicht böse, dass ihr den gesamten Quelltext zu lesen bekommt, ich will nur, dass ihr mein Problem versteht...
Huhu
$dh=@fopen("members/$user/session.ghi","r+");
[...]
if(session_id() == @file_get_contents("members/$user/session.ghi")){
[...]
@fclose($dh);
Wo liegt hier der Fehler? Bin ich weider mal zu blond, so was zu machen?
Mmmmh, Du unterdrückst Fehlermeldungen, hast aber keine eigene Fehlerbehandlung eingebaut.
Jetzt sitzt Du ohne Fehlermeldung da und weisst nicht warum es nicht funktioniert.
Das ist nicht wirklich schlau, oder?
Also einfach mal die @s entfernen und am Anfang des Skriptes folgendes
ergänzen
ini_set('display_errors', true);
ini_set('error_reporting', E_ALL);
Würde mich wundern wenn der Parser dann nicht zum "Singvogel" wird.
Viele Grüße
lulu
Huhu
:) dir auch "huhu"
$dh=@fopen("members/$user/session.ghi","r+");
[...]
if(session_id() == @file_get_contents("members/$user/session.ghi")){
[...]
@fclose($dh);
Also einfach mal die @s entfernen und am Anfang des Skriptes folgendes
ergänzen
Dann würden auf jeden Fall Fehlermeldungen kommen, weil zu anfang nämlich kein Query "user" übergeben wird. Er könnte also die datei members//session.ghi nicht finden.
Ich habe die @s mit Absicht eingebaut, damit eben so etwas nicht passiert, und das PHP-Skript nur etwas macht, wenn der Query "user" gegeben ist.
Aber dir zuliebe habe ich das trotzdem gemacht. Das ergebnis ist aber genau, wie ich es dir gesagt habe:
Notice: Undefined variable: user in /var/www/html/u/myrte/forum/index.php on line 36
Warning: fopen(members//session.ghi): failed to open stream: No such file or directory in /var/www/html/u/myrte/forum/index.php on line 36
Notice: Undefined variable: user in /var/www/html/u/myrte/forum/index.php on line 39
Warning: file_get_contents(members//session.ghi): failed to open stream: No such file or directory in /var/www/html/u/myrte/forum/index.php on line 39
Warning: fclose(): supplied argument is not a valid stream resource in /var/www/html/u/myrte/forum/index.php on line 68
Zuerst sagt er, die Variable user sei nicht gegeben (stimmt, ist sie ja auch nicht) und dann, dass er den Pfad nicht öffnen kann. Demnach kann er ihn auch nicht schließen...
Tja, der Fehler ist immer noch nicht gelöst, weil ich anscheinend schon eingeloggt bin, wenn ich auf die Seite komme. Also genau wie davor, die Löschung der @s hat mich keinen schritt weitergebracht...
Hallo
Dann würden auf jeden Fall Fehlermeldungen kommen, weil zu anfang nämlich kein Query "user" übergeben wird. Er könnte also die datei members//session.ghi nicht finden.
Aha, und wann kommt eine Fehlermeldung?
Richtig, der Kandidat erhält 100 Punkte, wenn es einen Fehler gibt.
Du hast eine nicht initialisierte Variable $user.
Offenbar arbeitet Dein Skript noch mit "register globals = on", das wäre eine Möglichkeit warum es online nicht funktioniert.
Also müsstest Du ungefähr so etwas bauen:
$user = isset($_GET['user']) && preg_match('#[a-z]+#i', $_GET['user'] )
? $_GET['user']
: false;
Hier werden nur Wert für "user" akzeptiert welche aus "a-zA-Z" bestehen
und per GET übergeben werden.
Die Abfragen dann ungefähr so erweitern
$fn = "members/$user/session.ghi";
if ($user !== false && file_exists($fn) && session_id() == file_get_contents($fn)):
// tue dies und das
endif;
Viele Grüße
lulu
Grrr
wenn man es schon macht dann wenigstens richtig
$user = isset($_GET['user']) && preg_match('#[a-z]+#i', $_GET['user'] )
? $_GET['user']
: false;
das vergiss mal gleich wieder - so isses richtig:
$user = isset($_GET['user']) && preg_match('#[1]+$#i', $_GET['user'] )
? $_GET['user']
: false;
Es soll ja der gesamt user-Parameter und nicht nur ein Teil gematched werden.
Viele Grüße
lulu
a-z ↩︎
$user = isset($_GET['user']) && preg_match('#[1]+$#i', $_GET['user'] )
? $_GET['user']
: false;
Könntest du das bitte als normale if()-Abfrage schreiben. Ich kapiere diese schreibweise nicht.
Ach ja, warum suchst du etwas im Query "user"? Das ergibt für mich keinen sinn... Für was soll das gut sein?
a-z ↩︎
Huhu
$user = isset($_GET['user']) && preg_match('#[1]+$#i', $_GET['user'] )
? $_GET['user']
: false;Könntest du das bitte als normale if()-Abfrage schreiben. Ich kapiere diese schreibweise nicht.
Ist eigentlich ganz einfach
$var = (Ausdruck) ? (wenn wahr (true) nimm dies) : (wenn unwahr(false) nimm das );
oder halt
$user = false;
if (isset($_GET['user']) && preg_match('#[2]+$#i', $_GET['user'] )){
$user = $_GET['user'];
}
oder auch
if (isset($_GET['user']) && preg_match('#[3]+$#i', $_GET['user'] )){
$user = $_GET['user'];
}else{
$user = false;
}
Ach ja, warum suchst du etwas im Query "user"? Das ergibt für mich keinen sinn... Für was soll das gut sein?
Keine Ahnung, ist ja Dein Skript.
Ich erlaube mir aus Deinem Posting zu zitieren:
<quote>
Dann würden auf jeden Fall Fehlermeldungen kommen, weil zu anfang nämlich kein Query "user" übergeben wird. Er könnte also die datei members//session.ghi nicht finden.
Ich habe die @s mit Absicht eingebaut, damit eben so etwas nicht passiert, und das PHP-Skript nur etwas macht, wenn der Query "user" gegeben ist.
</quote>
Viele Grüße
lulu
Hallo,
Also einfach mal die @s entfernen und am Anfang des Skriptes folgendes
ergänzenDann würden auf jeden Fall Fehlermeldungen kommen, weil zu anfang nämlich kein Query "user" übergeben wird. Er könnte also die datei members//session.ghi nicht finden.
Ich habe die @s mit Absicht eingebaut, damit eben so etwas nicht passiert, und das PHP-Skript nur etwas macht, wenn der Query "user" gegeben ist.
schon mal was davon gehört, dass es den Befehl isset -- Prüft die Existenz einer Variablen gibt?
mfg
Twilo
schon mal was davon gehört, dass es den Befehl isset -- Prüft die Existenz einer Variablen gibt?
Natürlich, aber das löst mein Problem nicht. Damit verändere ich den Code, aber ich bin anscheinend trotzdem eingeloggt, wenn ich auf die Seite gehe. Bin ich aber definitiv nicht